javascript - Axios 补丁中使用的不同标头
问题描述
我花了一个小时查看 Chrome 控制台,但看不到这个错误来自哪里。
我正在更新我的 Vue 应用程序中的 OAuth 实现。
故事从socialLink.js
发现必须创建新用户开始。Vue 组件 Vue-authentication 取决于access_token
响应中的存在,所以我返回一些虚拟文本:
return api.sendResponse(res, { email, name, socialId, access_token: 'abcd' });
库将此值存储在localStorage
:
重定向后,SignUp.vue
呈现并完成表单。与服务器的第一次通信是创建新用户的 Vuex 调用:
response = await this.$store.dispatch('CREATE_USER_PROFILE', payload);
它返回一个真正短暂的 JWT 令牌:
const token = auth.createToken(userId, nickname, new Date(), null, false, '1m');
return api.sendCreated(res, api.createResponse(token));
之后我将其存储在 Vue 页面中:
const { data } = response;
const token = data.data;
if (token === undefined) {
this.error = this.$t('sign-up.something-went-wrong');
return false;
}
我检查了令牌是否包含服务器返回的内容:
Request URL: https://beta.mezinamiridici.cz/api/v1/users
Request Method: POST
Status Code: 201 Created
{"success":true,"data":"eyJhbGciOiJIUzI1NiIs...Tl8JFw2HZ3VMXJk"}
然后我调用另一个 Vuex 方法并传递当前的 JWT 令牌:
await this.$store.dispatch('UPDATE_USER_PROFILE', {
我在 Vuex 开发工具中检查了确实存在正确的 JWT 令牌。然后我将它进一步传递给api.js
.
在这里,我创建了一个包含标头的 Axios 配置Authorization
:
function getAuthHeader(context, jwt = undefined, upload) {
const config = { headers: { } };
if (jwt || (context && context.rootState.users.userToken)) {
config.headers.Authorization = `bearer ${jwt || context.rootState.users.userToken}`;
}
我再次检查了那里使用了正确的 JWT 令牌。
最后,我将所有数据传递给 Axios:
function patch(endpoint, url, body, context, jwt) {
const headers = getAuthHeader(context, jwt);
console.log(headers);
if (endpoint === 'BFF') {
return axios.patch(`${VUE_APP_BFF_ENDPOINT}${url}`, body, headers);
} else {
return axios.patch(`${VUE_APP_API_ENDPOINT}${url}`, body, headers);
}
}
我记录并可以确认正确的 JWT 仍然存在:
bearer eyJhbGciOiJIUzI1N....8JFw2HZ3VMXJk
现在没有什么可以将标题更改为abcd
,但是,“网络”选项卡显示了它:
服务器因解析错误而失败。
有没有人知道为什么 Axios 使用的Authorization
标头与我传递的值不同?
解决方案
好的,谜团解开了。vue-authenticate
是原因,因为它创建了 Axios 拦截器并Authorization
自己处理标头。
vue-authenticate.common.js
:
var defaultOptions = {
bindRequestInterceptor: function ($auth) {
var tokenHeader = $auth.options.tokenHeader;
$auth.$http.interceptors.request.use(function (config) {
if ($auth.isAuthenticated()) {
config.headers[tokenHeader] = [
$auth.options.tokenType, $auth.getToken()
].join(' ');
} else {
delete config.headers[tokenHeader];
}
return config
});
},
我的代码更复杂,它支持带有电子邮件/密码的内部帐户,所以这个代码破坏了我的。拦截器必须存在并且是一个函数,所以解决方案是:
Vue.use(VueAuthenticate, {
tokenName: 'jwt',
baseUrl: process.env.VUE_APP_API_ENDPOINT,
storageType: 'localStorage',
bindRequestInterceptor() {},
bindResponseInterceptor() {},
providers: {
facebook: {
clientId: process.env.VUE_APP_FACEBOOK_CLIENT_ID,
redirectUri: process.env.VUE_APP_FACEBOOK_REDIRECT_URI,
},
推荐阅读
- c# - 如何在插入失败时获取冲突行的主键?
- sql - 如何从 postgres 函数返回两个 SELECT 语句的结果?
- python - 如何找到所有正好有六个 1 和其余 0 的 32 位二进制数
- jquery - Chrome 中的 Ajax 同步请求失败
- google-cloud-firestore - 是否可以查询 DocumentReference[] 数组?
- reactjs - 获取后如何从道具设置初始状态?
- regex - 正则表达式正在寻找匹配但如果只匹配一次则不计数
- angular - 如何使用 observable 动态更新 Angular Material Table
- mysql - 使用 2 个选择优化 SQL 查询
- python - 重置 Tkinter 窗口,恢复小部件