【问题标题】:How to send Basic Auth with axios如何使用 axios 发送基本身份验证
【发布时间】:2017-10-19 17:50:33
【问题描述】:

我正在尝试实现以下代码,但有些东西不起作用。代码如下:

      var session_url = 'http://api_address/api/session_endpoint';
      var username = 'user';
      var password = 'password';
      var credentials = btoa(username + ':' + password);
      var basicAuth = 'Basic ' + credentials;
      axios.post(session_url, {
        headers: { 'Authorization': + basicAuth }
      }).then(function(response) {
        console.log('Authenticated');
      }).catch(function(error) {
        console.log('Error on Authentication');
      });

它返回 401 错误。当我使用 Postman 执行此操作时,可以选择设置基本身份验证;如果我不填写这些字段,它也会返回 401,但如果我填写,则请求成功。

任何想法我做错了什么?

以下是 API 文档的一部分,介绍了如何实现这一点:

此服务使用标头中的基本身份验证信息来建立用户会话。凭据根据服务器进行验证。使用此 Web 服务将使用传递的用户凭据创建一个会话并返回一个 JSESSIONID。此 JSESSIONID 可用于后续请求以进行 Web 服务调用。*

【问题讨论】:

    标签: request postman axios


    【解决方案1】:

    Basic Auth 有一个“auth”参数:

    auth: {
      username: 'janedoe',
      password: 's00pers3cret'
    }
    

    来源/文档:https://github.com/mzabriskie/axios

    例子:

    await axios.post(session_url, {}, {
      auth: {
        username: uname,
        password: pass
      }
    });
    

    【讨论】:

    • 你好,我怎样才能将它设置到所有的 axios 调用中?我需要将基本身份验证添加到所有 ajax 调用。 axios.defaults.auth = { username: 'dd', password: '##'} 这对我不起作用。
    • 顺便说一句,你也可以为这些事情写一个围绕 axios 的包装器
    • 我为此做了包装。但是那个 api 给了我 401 错误
    • @hkg328 如果要手动设置标头,则需要将字符串 username:password 编码为 base64。类似于 import btoa from 'btoa-lite' 的东西; token = btoa(用户名 + ':' + 密码);然后将标头设置为 'Basic' + token;
    【解决方案2】:

    您问题中的代码未通过身份验证的原因是因为您在数据对象中发送身份验证,而不是在配置中,这会将其放在标题中。根据axios docspost请求方法别名是:

    axios.post(url[, data[, config]])

    因此,为了让您的代码正常工作,您需要发送一个空对象作为数据:

    var session_url = 'http://api_address/api/session_endpoint';
    var username = 'user';
    var password = 'password';
    var basicAuth = 'Basic ' + btoa(username + ':' + password);
    axios.post(session_url, {}, {
      headers: { 'Authorization': + basicAuth }
    }).then(function(response) {
      console.log('Authenticated');
    }).catch(function(error) {
      console.log('Error on Authentication');
    });
    

    @luschn 提到的使用 auth 参数也是如此。以下代码是等价的,但使用了 auth 参数(并且还传递了一个空数据对象):

    var session_url = 'http://api_address/api/session_endpoint';
    var uname = 'user';
    var pass = 'password';
    axios.post(session_url, {}, {
      auth: {
        username: uname,
        password: pass
      }
    }).then(function(response) {
      console.log('Authenticated');
    }).catch(function(error) {
      console.log('Error on Authentication');
    });
    

    【讨论】:

    • 这有帮助,谢谢
    • 这应该是公认的答案。接受的答案只是文档的副本。
    • 不需要 2020 年 11 月的那个:github.com/axios/axios#axiosrequestconfigdG9tbzp0b21vOTgy
    • 在第二个代码示例中无法使用 auth 对象。如第一个代码示例所示,使用 base64 转换工作正常。
    【解决方案3】:

    在 Node.js 中使用 Axios 的示例(axios_example.js):

    const axios = require('axios');
    const express = require('express');
    const app = express();
    const port = process.env.PORT || 5000;
    
    app.get('/search', function(req, res) {
        let query = req.query.queryStr;
        let url = `https://your.service.org?query=${query}`;
    
        axios({
            method:'get',
            url,
            auth: {
                username: 'xxxxxxxxxxxxx',
                password: 'xxxxxxxxxxxxx'
            }
        })
        .then(function (response) {
            res.send(JSON.stringify(response.data));
        })
        .catch(function (error) {
            console.log(error);
        });
    });
    
    var server = app.listen(port);
    

    确保在您的项目目录中执行以下操作:

    npm init
    npm install express
    npm install axios
    node axios_example.js
    

    然后您可以使用浏览器测试 Node.js REST API:http://localhost:5000/search?queryStr=xxxxxxxxx

    参考:https://github.com/axios/axios

    【讨论】:

      【解决方案4】:

      由于某些原因,这个简单的问题阻碍了许多开发人员。我为这个简单的事情挣扎了好几个小时。这个问题多维度:

      1. CORS(如果您在不同的域和端口上使用前端和后端。
      2. 后端 CORS 配置
      3. Axios 的基本认证配置

      CORS

      我的开发设置是使用在 localhost:8081 上运行的 vuejs webpack 应用程序和在 localhost:8080 上运行的 Spring Boot 应用程序。因此,当尝试从前端调用 rest API 时,如果没有正确的 CORS 设置,浏览器将无法让我收到来自 spring 后端的响应。 CORS 可用于放松现代浏览器所具有的跨域脚本 (XSS) 保护。据我了解,浏览器正在保护您的 SPA 免受 XSS 的攻击。当然,StackOverflow 上的一些答案建议添加一个 chrome 插件来禁用 XSS 保护,但这确实有效,如果是这样,只会将不可避免的问题推到以后。

      后端 CORS 配置

      以下是在 Spring Boot 应用中设置 CORS 的方法:

      添加一个 CorsFilter 类以在对客户端请求的响应中添加适当的标头。 Access-Control-Allow-Origin 和 Access-Control-Allow-Headers 是基本身份验证最重要的东西。

          public class CorsFilter implements Filter {
      
      ...
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              HttpServletResponse response = (HttpServletResponse) servletResponse;
              HttpServletRequest request = (HttpServletRequest) servletRequest;
      
              response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
              response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
              **response.setHeader("Access-Control-Allow-Headers", "authorization, Content-Type");**
              response.setHeader("Access-Control-Max-Age", "3600");
      
              filterChain.doFilter(servletRequest, servletResponse);
      
          }
      ...
      }
      

      添加一个扩展 Spring WebSecurityConfigurationAdapter 的配置类。在本课程中,您将注入您的 CORS 过滤器:

      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      ...
          @Bean
          CorsFilter corsFilter() {
              CorsFilter filter = new CorsFilter();
              return filter;
          }
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
      
              http.addFilterBefore(corsFilter(), SessionManagementFilter.class) //adds your custom CorsFilter
                .csrf()
                .disable()
                .authorizeRequests()
                .antMatchers("/api/login")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                .authenticationProvider(getProvider());
          }
      ...
      }
      

      您不必在控制器中放置与 CORS 相关的任何内容。

      前端

      现在,您需要在前端创建带有 Authorization 标头的 axios 查询:

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
          <script src="https://unpkg.com/vue"></script>
          <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
      </head>
      <body>
      <div id="app">
          <p>{{ status }}</p>
      </div>
      <script>
          var vm = new Vue({
              el: "#app",
              data: {
                  status: ''
              },
              created: function () {
                  this.getBackendResource();
              },
              methods: {
                  getBackendResource: function () {
                      this.status = 'Loading...';
                      var vm = this;
                      var user = "aUserName";
                      var pass = "aPassword";
                      var url = 'http://localhost:8080/api/resource';
      
                      var authorizationBasic = window.btoa(user + ':' + pass);
                      var config = {
                          "headers": {
                              "Authorization": "Basic " + authorizationBasic
                          }
                      };
                      axios.get(url, config)
                          .then(function (response) {
                              vm.status = response.data[0];
                          })
                          .catch(function (error) {
                              vm.status = 'An error occured.' + error;
                          })
                  }
              }
          })
      </script>
      </body>
      </html>
      

      希望这会有所帮助。

      【讨论】:

      • noob CORS 问题,这只是在开发中使用的,对吧?
      • 不,它也在生产中。
      【解决方案5】:

      luschn 和 pillravi 给出的解决方案可以正常工作,除非您在响应中收到 Strict-Transport-Security 标头。

      添加 withCredentials: true 将解决该问题。

        axios.post(session_url, {
          withCredentials: true,
          headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
          }
        },{
          auth: {
            username: "USERNAME",
            password: "PASSWORD"
        }}).then(function(response) {
          console.log('Authenticated');
        }).catch(function(error) {
          console.log('Error on Authentication');
        });
      

      【讨论】:

      • 数据呢
      【解决方案6】:

      如果您尝试进行基本身份验证,可以尝试以下操作:

      const username = ''
      const password = ''
      
      const token = Buffer.from(`${username}:${password}`, 'utf8').toString('base64')
      
      const url = 'https://...'
      const data = {
      ...
      }
      
      axios.post(url, data, {
        headers: {
       'Authorization': `Basic ${token}`
      },
      })
      

      这对我有用。希望有帮助

      【讨论】:

        【解决方案7】:

        您好,您可以通过以下方式进行操作

            var username = '';
            var password = ''
        
            const token = `${username}:${password}`;
            const encodedToken = Buffer.from(token).toString('base64');
            const session_url = 'http://api_address/api/session_endpoint';
        
            var config = {
              method: 'get',
              url: session_url,
              headers: { 'Authorization': 'Basic '+ encodedToken }
            };
        
            axios(config)
            .then(function (response) {
              console.log(JSON.stringify(response.data));
            })
            .catch(function (error) {
              console.log(error);
            });
        

        【讨论】:

        • 这应该是选择的答案。我必须从接受的答案中拼凑出正确的形式,这对我不起作用。此解决方案有效。
        • 谢谢,这个解决方案完美!
        【解决方案8】:

        我刚遇到这个问题,做了一些研究发现数据值必须作为 URLSearchParams 发送,我这样做是这样的:

        getAuthToken: async () => {
        const data = new URLSearchParams();
        data.append('grant_type', 'client_credentials');
        const fetchAuthToken = await axios({
          url: `${PAYMENT_URI}${PAYMENT_GET_TOKEN_PATH}`,
          method: 'POST',
          auth: {
            username: PAYMENT_CLIENT_ID,
            password: PAYMENT_SECRET,
          },
          headers: {
            Accept: 'application/json',
            'Accept-Language': 'en_US',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Access-Control-Allow-Origin': '*',
          },
          data,
          withCredentials: true,
        });
        return fetchAuthToken;
        

        },

        【讨论】:

          【解决方案9】:

          我使用 axios.interceptors.request.use 来配置基本身份验证凭据。我有一个带有简单 GET 端点的后端 Springboot(带有 SpringSecurity)应用程序。前端 VueJs 应用程序和后端在不同的端口上运行。

          axios.js

          import axios from "axios";
          
          const api = axios.create({
            baseURL: "http://api_address",
            timeout: 30000,
          });
          
          api.interceptors.request.use(
            async (config) => {
              const basicAuthCredentials = btoa("xxxx" + ":" + "xxxx");
              config.headers.common["Authorization"] = "Basic " + basicAuthCredentials;
              return config;
            },
            (error) => {
              return Promise.reject(error);
            }
          );
          
          export default api;
          

          后端.js

          import axios from "@/services/axios";
          
          const BackendAPI = {
          
            listUsers: async () => {
              return axios({
                url: '/users',
                method: 'GET',
                responseType: 'json',
              });
            },
          };
          
          export { BackendAPI };
          

          后跟VUE组件Users.vue

          ...
          <script>
          import { BackendAPI } from '@/services/backend';
          
          export default {
            name: "Users",
            data() {
              return {
                usersList: [],
              }
            },
            methods: {
              async listUsers() {
                const response = await BackendAPI.listUsers();
                this.usersList = response.data;
              },
            },
          };
          </script>
          

          后端 spring SecurityConfig.java 使用 httpBasic 作为身份验证并且禁用了 cors 和 csrf。

          @Configuration
          @EnableWebSecurity
          public class SecurityConfig extends WebSecurityConfigurerAdapter {
          
            @Override
            protected void configure(HttpSecurity http) throws Exception {
              http.authorizeRequests()
                  .antMatchers("/actuator/*")
                  .permitAll()
                  .anyRequest()
                  .authenticated()
                  .and()
                  .httpBasic()
                  .and()
                  .cors()
                  .disable()
                  .csrf()
                  .disable();
            }
          }
          

          【讨论】:

            【解决方案10】:
            const auth = {
                        username : 'test',
                        password : 'test'
                    }
            const response =  await axios.get(yourUrl,{auth}) 
            

            如果您使用基本身份验证,这是可行的

            【讨论】:

            • 这似乎与已经接受的答案相匹配。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-30
            • 2018-10-08
            • 1970-01-01
            • 2020-10-31
            • 2015-05-13
            • 2017-06-18
            • 2018-07-19
            相关资源
            最近更新 更多