我已经建立了一个使用API的AngularJS网站.此API提供的功能很少,如身份验证(Oauth).
当API返回401错误时,表示access_token已过期,需要使用refresh_token刷新.
我在AngularJS中创建了一个拦截器.其目标是检查API返回的结果是否为401错误,如果是这种情况,则必须刷新令牌,然后处理先前被拒绝的请求.
问题是拦截器创建了一个无限循环.在初始请求的第二次失败之后,它应该停止但它不会.
angular.module('myApp') .factory('authInterceptor',function ($rootScope,$q,$window,$injector) { return { // If the API returns an error 'responseError' : function(rejection) { // If it's a 401 if (rejection.status == 401) { var deferred = $q.defer(); $injector.get('$http').post('http://my-api.local/api/oauth/token',{ grant_type : 'refresh_token',client_id : 'id',client_secret : 'secret',refresh_token : $window.sessionStorage.refresh_token },{ headers : { 'Content-Type' : 'application/x-www-form-urlencoded' },transformRequest : function(obj) { var str = []; for(var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); } }) // New token request successfull .success(function(refreshResponse) { // Processing the Failed request again (should fail again because I didn't saved the new tokens) $injector.get('$http')(rejection.config).success(function(data) { deferred.resolve(data); }) .error(function(error,status) { deferred.reject(); }); return deferred.promise(); }) // New token request failure .error(function(error,status) { deferred.reject(); // $location.path('users/login'); return; }); } // If it's another errorenter code here else return rejection; } } });
所以这段代码:
>第一个请求失败时启动
>刷新令牌
>重试请求但又失败了(< - 我只是想让它停在这里)
>刷新令牌
>重试请求但又失败了
>刷新令牌
>重试请求但又失败了
>等……
解决方法
我在我的应用程序中进行了此操作.您的刷新请求需要包含一个config / header变量,如skipIntercept:true.然后,当您将此作为失败的响应进行拦截时,可以检查rejection.config.skipIntercept变量.如果是真的,你直接进入$q.reject(拒绝).
你在哪里:
if (rejection.status == 401) {
将其更改为:
if (rejection.status == 401 && !rejection.config.skipIntercept) {
然后在上面:
headers : { 'Content-Type' : 'application/x-www-form-urlencoded' },
你需要添加:
skipIntercept: true,headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
PS.你可以使用there’s an existing solution.