当访问令牌过期并且我们需要再次登录以继续作为普通用户时,我们如何保持用户登录
How can we maintain user logged in when access token expires and we need to login again to continue as normal user
我正在使用 Nuxt-axios 模块和代理。
对于错误处理,我在
中有通用代码
Plugins/axios.js
export default function({ $axios, __isRetryRequest, store, app, redirect , payload , next}) {
$axios.onRequest(config => {
if (app.$cookies.get('at') && app.$cookies.get('rt') && config.url != '/post_login/') {
config.headers.common['Authorization'] = `Bearer ${app.$cookies.get('at')}`;
}
});
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status)
let originalRequest = err.config;
if (code === 401) {
originalRequest.__isRetryRequest = true;
store
.dispatch('LOGIN', { grant_type: 'refresh_token', refresh_token: app.$cookies.get('rt')})
.then(res => {
originalRequest.headers['Authorization'] = 'Bearer ' + app.$cookies.get('at');
return app.$axios(originalRequest);
})
.catch(error => {
console.log(error);
});
}
// code for 422 error
if (code == 422) {
throw err.response;
}
});
}
在我的页面文件夹索引页
Pages/index.vue
<template>
<section>Component data</section>
</template>
<script type="text/javascript">
export default {
async asyncData({ route, store }) {
await store.dispatch('GET_BANNERS');
}
}
</script>
所有 API 调用都在 stroes/actions.js 文件中。
现在的问题是当我刷新页面时 index.vue 首先 API 请求将命中并在成功时得到响应。但是现在如果第一次请求( 'GET_BANNERS' )来自 asyncData 并且它得到 401 错误未授权然后我得到低于错误
Error: Request failed with status code 401
错误[ERR_HTTP_HEADERS_SENT]:发送给客户端后无法设置headers
我该如何解决这个问题?
还有几个问题:
1) 当我在 axios 中编写常见错误代码时,收到 401 的原始请求如何设置数据再次存储(我们通常从操作文件中执行)?
2) 任何人都可以帮助最佳实践附加授权 headers 和 400,401,422 等的错误句柄。
错误 ERR_HTTP_HEADERS_SENT
表示您的 server-side 代码中存在错误 - 因此此错误的错误出现在 HTTP headers.
之前
要处理 4xx 错误并重试 Axios 请求 - 请遵循以下示例:
Vue.prototype.$axios = axios.create(
{
headers:
{
'Content-Type': 'application/json',
},
baseURL: process.env.API_URL
}
);
Vue.prototype.$axios.interceptors.request.use(
config =>
{
events.$emit('show_spin');
let token = getTokenID();
if(token && token.length) config.headers['Authorization'] = token;
return config;
},
error =>
{
events.$emit('hide_spin');
if (error.status === 401) VueRouter.push('/login');
else throw error;
}
);
Vue.prototype.$axios.interceptors.response.use(
response =>
{
events.$emit('hide_spin');
return response;
},
error =>
{
events.$emit('hide_spin');
return new Promise(function(resolve,reject)
{
if (error.config && error.response && error.response.status === 401 && !error.config.__isRetry)
{
myVue.refreshToken(function()
{
error.config.__isRetry = true;
error.config.headers['Authorization'] = getTokenID();
myVue.$axios(error.config).then(resolve,reject);
},function(flag) // true = invalid session, false = something else
{
if(process.env.NODE_ENV === 'development') console.log('Could not refresh token');
if(getUserID()) myVue.showFailed('Could not refresh the Authorization Token');
reject(flag);
});
}
else throw error;
});
}
);
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status);
let originalRequest = err.config;
if (code == 401) {
originalRequest.__isRetryRequest = true;
let token = app.$cookies.get('rt');
return new Promise((resolve, reject) => {
let req = $axios
.post(`/login`, { grant_type: 'refresh_token', refresh_token: token })
.then(response => {
if (response.status == 200) {
app.$cookies.set('access', response.data.access_token);
app.$cookies.set('refresh', response.data.refresh_token);
originalRequest.headers['Authorization'] = `Bearer ${
response.data.access_token
}`;
}
resolve(response);
}).catch(e => {
reject("some message");
})
})
.then(res => {
return $axios(originalRequest);
}).catch(e => {
app.router.push('/login');
});
}
});
@canet-robern 希望这能解决您的问题!!
我正在使用 Nuxt-axios 模块和代理。
对于错误处理,我在
中有通用代码Plugins/axios.js
export default function({ $axios, __isRetryRequest, store, app, redirect , payload , next}) {
$axios.onRequest(config => {
if (app.$cookies.get('at') && app.$cookies.get('rt') && config.url != '/post_login/') {
config.headers.common['Authorization'] = `Bearer ${app.$cookies.get('at')}`;
}
});
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status)
let originalRequest = err.config;
if (code === 401) {
originalRequest.__isRetryRequest = true;
store
.dispatch('LOGIN', { grant_type: 'refresh_token', refresh_token: app.$cookies.get('rt')})
.then(res => {
originalRequest.headers['Authorization'] = 'Bearer ' + app.$cookies.get('at');
return app.$axios(originalRequest);
})
.catch(error => {
console.log(error);
});
}
// code for 422 error
if (code == 422) {
throw err.response;
}
});
}
在我的页面文件夹索引页
Pages/index.vue
<template>
<section>Component data</section>
</template>
<script type="text/javascript">
export default {
async asyncData({ route, store }) {
await store.dispatch('GET_BANNERS');
}
}
</script>
所有 API 调用都在 stroes/actions.js 文件中。
现在的问题是当我刷新页面时 index.vue 首先 API 请求将命中并在成功时得到响应。但是现在如果第一次请求( 'GET_BANNERS' )来自 asyncData 并且它得到 401 错误未授权然后我得到低于错误
Error: Request failed with status code 401
错误[ERR_HTTP_HEADERS_SENT]:发送给客户端后无法设置headers
我该如何解决这个问题?
还有几个问题:
1) 当我在 axios 中编写常见错误代码时,收到 401 的原始请求如何设置数据再次存储(我们通常从操作文件中执行)?
2) 任何人都可以帮助最佳实践附加授权 headers 和 400,401,422 等的错误句柄。
错误 ERR_HTTP_HEADERS_SENT
表示您的 server-side 代码中存在错误 - 因此此错误的错误出现在 HTTP headers.
要处理 4xx 错误并重试 Axios 请求 - 请遵循以下示例:
Vue.prototype.$axios = axios.create(
{
headers:
{
'Content-Type': 'application/json',
},
baseURL: process.env.API_URL
}
);
Vue.prototype.$axios.interceptors.request.use(
config =>
{
events.$emit('show_spin');
let token = getTokenID();
if(token && token.length) config.headers['Authorization'] = token;
return config;
},
error =>
{
events.$emit('hide_spin');
if (error.status === 401) VueRouter.push('/login');
else throw error;
}
);
Vue.prototype.$axios.interceptors.response.use(
response =>
{
events.$emit('hide_spin');
return response;
},
error =>
{
events.$emit('hide_spin');
return new Promise(function(resolve,reject)
{
if (error.config && error.response && error.response.status === 401 && !error.config.__isRetry)
{
myVue.refreshToken(function()
{
error.config.__isRetry = true;
error.config.headers['Authorization'] = getTokenID();
myVue.$axios(error.config).then(resolve,reject);
},function(flag) // true = invalid session, false = something else
{
if(process.env.NODE_ENV === 'development') console.log('Could not refresh token');
if(getUserID()) myVue.showFailed('Could not refresh the Authorization Token');
reject(flag);
});
}
else throw error;
});
}
);
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status);
let originalRequest = err.config;
if (code == 401) {
originalRequest.__isRetryRequest = true;
let token = app.$cookies.get('rt');
return new Promise((resolve, reject) => {
let req = $axios
.post(`/login`, { grant_type: 'refresh_token', refresh_token: token })
.then(response => {
if (response.status == 200) {
app.$cookies.set('access', response.data.access_token);
app.$cookies.set('refresh', response.data.refresh_token);
originalRequest.headers['Authorization'] = `Bearer ${
response.data.access_token
}`;
}
resolve(response);
}).catch(e => {
reject("some message");
})
})
.then(res => {
return $axios(originalRequest);
}).catch(e => {
app.router.push('/login');
});
}
});
@canet-robern 希望这能解决您的问题!!