我试图实现以下代码,但有些东西是不工作的。代码如下:

      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错误。当我用邮差做的时候,有一个选项可以设置基本认证;如果我没有填写这些字段,它也会返回401,但如果我填写了,请求就成功了。

知道我哪里做错了吗?

下面是如何实现这个API的部分文档:

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


当前回答

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

CORS(如果你在不同的域和端口上使用前端和后端。 后端CORS配置 Axios的基本身份验证配置

CORS

My setup for development is with a vuejs webpack application running on localhost:8081 and a spring boot application running on localhost:8080. So when trying to call rest API from the frontend, there's no way that the browser will let me receive a response from the spring backend without proper CORS settings. CORS can be used to relax the Cross Domain Script (XSS) protection that modern browsers have. As I understand this, browsers are protecting your SPA from being an attack by an XSS. Of course, some answers on StackOverflow suggested to add a chrome plugin to disable XSS protection but this really does work AND if it was, would only push the inevitable problem for later.

后端CORS配置

以下是在春季启动应用程序中设置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>

希望这能有所帮助。

其他回答

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

CORS(如果你在不同的域和端口上使用前端和后端。 后端CORS配置 Axios的基本身份验证配置

CORS

My setup for development is with a vuejs webpack application running on localhost:8081 and a spring boot application running on localhost:8080. So when trying to call rest API from the frontend, there's no way that the browser will let me receive a response from the spring backend without proper CORS settings. CORS can be used to relax the Cross Domain Script (XSS) protection that modern browsers have. As I understand this, browsers are protecting your SPA from being an attack by an XSS. Of course, some answers on StackOverflow suggested to add a chrome plugin to disable XSS protection but this really does work AND if it was, would only push the inevitable problem for later.

后端CORS配置

以下是在春季启动应用程序中设置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>

希望这能有所帮助。

在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

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

裁判:https://github.com/axios/axios

const auth = {
            username : 'test',
            password : 'test'
        }
const response =  await axios.get(yourUrl,{auth}) 

如果使用基本认证,这就是工作

问题中的代码没有进行身份验证的原因是您在数据对象中发送身份验证,而不是在配置中发送,配置将把它放在报头中。根据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');
});

基本认证有一个“auth”参数:

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

来源/ Docs: https://github.com/mzabriskie/axios

例子:

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