我刚开始使用vue和vue资源。 在后端我使用laravel,我处理jwt令牌。 每个请求都会刷新令牌。到目前为止,这种方法很有效,除了一种情况 如果我使用vue资源连续发送两个请求,如下所示:
//first request
Vue.http.get('/api/runs').then((response) => {
return response.json();
}, (response) => {
console.log(response);
this.$set('error', {'status' : response.status, 'error': response.statusText});
});
//second request
Vue.http.get('/api/meta').then((response) => {
return response.json();
}, (response) => {
console.log(response);
this.$set('error', {'status' : response.status, 'error': response.statusText});
});
只有第一个请求具有有效令牌。 我通过拦截器设置令牌:
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = Auth.getAuthHeader();
request.emulateJSON = true;
next(function(response) {
if(response.headers['Authorization']) {
var token = response.headers['Authorization'];
localStorage.setItem('jwt-token', token);
}
});
});
发生这种情况,因为在拦截器可以设置新的jwt令牌之前,两个请求都是并行触发的。 所以我的问题是,如何强制第二个请求直到第一个请求完全完成或者我如何强制拦截器等待?
答案 0 :(得分:1)
我不认为你可以通过拦截器实现这一目标。 Promise是异步的。您需要将第二个请求放入第一个请求的成功回调中。但是,我认为在某些时候可能会出现不必要的混乱,并且还会从您的呼叫中消除异步能力。
我认为更好的解决方案是在后端API(Laravel/Passport)中专门为刷新令牌创建端点。您需要向端点发送refresh_token
以获取新的access_token
。让访问令牌的使用时间更长(因此您不会过多地刷新它们并减慢您的应用程序速度)。这是典型的OAuth2流程。这里是一个拦截器(VueJS 2.0和最新的Vue-resource 1.0.3),它将添加你的Auth头,并在拦截器获得无效的令牌响应时自动刷新令牌:
Vue.http.interceptors.push((request, next) => {
const token = "get your token from localStorage or Vuex here"
const hasAuthHeader = request.headers.has('Authorization')
if (token && !hasAuthHeader) {
request.headers.set('Authorization', 'Bearer ' + token)
}
next((response) => {
if (response.status === 401 && response.data.error === 'invalid_token') {
// Create this function below to get the new token and store
// it in localStorage and then retries the original request.
return refreshToken(request)
}
})
})
我会留下refreshToken(request)
函数给你写,但希望你能在这里得到这个想法。您可以进行调整并使用JWT。您可以查看我的VueJS 2.0 Example Project或更具体的Auth.js文件,了解我是如何实现刷新令牌功能的。