我目前正在使用以下代码重新抛出从我的API返回401的请求:
responseError: function(rejection) {
var authData = localStorageService.get('authorizationData');
if (rejection.status === 401 && authData) {
var authService = $injector.get('authService');
var $http = $injector.get('$http');
̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
var promise = authService.refreshToken();
return ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶ promise.then(function () {
return $http(rejection.config);
});
}
return $q.reject(rejection);
}
这适用于1个请求,但如果我从单个页面返回两个401,它似乎无法工作,例如当页面加载两个api调用以填充不同的部分时。如何让我的拦截器重新抛出多个延期调用?
另外,不应该为每个401单独拦截拦截器吗?不理想,它会在单个页面上引起多次刷新调用,但由于调用没有被重新抛出而导致数据丢失的改进。
截图:
答案 0 :(得分:1)
一种方法是保存令牌保证并链接第二次和后续重试,直到令牌刷新完成:
responseError: function(rejection) {
var authService = $injector.get('authService');
var $http = $injector.get('$http');
var tokenPromise = null;
var authData = localStorageService.get('authorizationData');
if (rejection.status === 401 && authData) {
if (!tokenPromise) {
tokenPromise = authService.refreshToken()
.finally(function() {
tokenPromise = null;
});
};
return tokenPromise.then(function () {
return $http(rejection.config);
});
} else {
throw rejection;
}
}
在上面的示例中,拒绝处理程序创建一个令牌刷新承诺,然后在令牌刷新结束(满足或拒绝)时使其为空。如果在令牌刷新过程中发生另一次拒绝,则以链接(并延迟)重试,直到令牌刷新XHR完成。
答案 1 :(得分:1)
非常相似的georgeawg答案......
responseError: function(rejection) {
var authData = localStorageService.get('authorizationData');
if (rejection.status === 401 && authData && !isAuthRequest() /* If request for refresh token fails itself do not go into loop, i.e. check by url */) {
var authService = $injector.get('authService');
var $http = $injector.get('$http');
var promise = authService.refreshTokenExt(); // look below
return ̶promise.then(function () {
return $http(rejection.config);
});
}
return $q.reject(rejection);
}
AuthService:
...
var refreshAuthPromise;
service.refreshTokenExt = function() {
if (refreshAuthPromise == null) {
refreshAuthPromise = authService.refreshToken().catch(function() {
// Cant refresh - redirect to login, show error or whatever
}).finally(function() {
refreshAuthPromise = null;
});
}
return refreshAuthPromise;
}