如何发送基本认证与axios

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

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

375945 次浏览

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

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

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

例子:

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

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

在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

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

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

歌珥

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

后端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>

希望这能有所帮助。

luschn和pillravi给出的解决方案工作得很好,除非你在响应中收到Strict-Transport-Security报头。

添加withCredentials:真将解决这个问题。

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

如果你正在尝试进行基本的验证,你可以试试这个:

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}`
},
})

这对我很管用。希望这能有所帮助

你好,你可以用下面的方法来做

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

我只是面对这个问题,做了一些研究,我发现数据值必须作为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;

},

我使用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;

backend.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();
}
}
const auth = {
username : 'test',
password : 'test'
}
const response =  await axios.get(yourUrl,{auth})

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