如何使用axios发送基本身份验证


107

我正在尝试实现以下代码,但某些方法无法正常工作。这是代码:

  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服务调用。*

Answers:


152

基本身份验证有一个“ auth”参数:

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

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

例:

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

4
您好,如何将其设置为所有axios调用?我需要将基本身份验证添加到所有ajax调用中。axios.defaults.auth = {用户名:'dd',密码:'##'}这对我不起作用。
hkg328

也许这会有所
luschn

顺便说一句,您也可以为此类问题在axios周围写一个包装器
luschn18,18年

我为此做包装。但是该API给我401错误
hkg328

1
@ hkg328,如果要手动设置标头,则需要将字符串username:password编码为base64。例如从“ btoa-lite”导入btoa;令牌= btoa(用户名+':'+密码); 然后将标头设置为“基本” +令牌;
shrumm '18

54

您问题中的代码未通过身份验证的原因是,您正在将验证发送到数据对象中,而不是在配置中发送,这会将它放在标头中。根据axios文档请求方法的别名post

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');
});

1
谢谢,谢谢
superrcoop '19

1
这应该是公认的答案。接受的答案只是文档的重复。
险恶胡子

5

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

  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-Header是基本身份验证中最重要的内容。

    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问题,这仅用于开发中,对吗?
Len Joseph

不,它也是并且主要在生产中。
Erick Audet

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


3

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

添加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');
  });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.