AngularJS – http拦截器 – 在令牌刷新后重新发送所有请求
发布时间:2020-12-17 08:09:07 所属栏目:安全 来源:网络整理
导读:我有一个有角度的应用程序,有时每个状态会执行多个$ http.get请求。该应用程序使用JWT进行用户验证刷新令牌。 API服务器在由于auth错误而失败的每个请求发送401。 我制作了一个http拦截器,请求一个新的令牌与401错误的刷新令牌,然后重新发送原始请求。 问
我有一个有角度的应用程序,有时每个状态会执行多个$ http.get请求。该应用程序使用JWT进行用户验证刷新令牌。 API服务器在由于auth错误而失败的每个请求发送401。
我制作了一个http拦截器,请求一个新的令牌与401错误的刷新令牌,然后重新发送原始请求。 问题是,如果状态例如2 $ http.get请求,并且都获得401响应,那么我更新访问令牌两次。显然我只想刷新一次令牌,但是我仍然想重新发送两个失败的请求。 这是可以实现的吗? app.factory('AuthInterceptor',function($q,$injector,RESOURCE_URL,API_BASE,authService) { return { request: function(config) { config.headers = config.headers || {}; if (authService.getAccessToken()) { if (config.url.substring(0,RESOURCE_URL.length) !== RESOURCE_URL) { config.headers.Authorization = 'Bearer ' + authService.getAccessToken(); } } return config; },responseError: function(response) { switch (response.status) { case 401: var deferred = $q.defer(); $injector.get("$http").post(API_BASE + '/api/auth/refresh',{refreshtoken: authService.getRefreshToken()}).then(function(r) { if (r.data.data.accesstoken && r.data.data.refreshtoken && r.data.data.expiresin) { authService.setAccessToken(r.data.data.accesstoken); authService.setRefreshToken(r.data.data.refreshtoken); authService.setExpiresIn(r.data.data.expiresin); $injector.get("$http")(response.config).then(function(resp) { deferred.resolve(resp); },function(resp) { deferred.reject(); }); } else { deferred.reject(); } },function(response) { deferred.reject(); authService.clear(); $injector.get("$state").go('guest.login'); return; }); return deferred.promise; break; default: authService.clear(); $injector.get("$state").go('guest.login'); break; } return response || $q.when(response); } }; });
你的拦截器需要跟踪它是否有飞行中的认证请求。它可以通过保留对认证请求返回的承诺的引用来做到这一点。如果有飞行中的请求,并且获得另一个401,只需使用缓存的承诺,而不是发起新的请求。
app.factory('AuthInterceptor',authService) { var inFlightAuthRequest = null; return { request: function(config) { config.headers = config.headers || {}; if (authService.getAccessToken()) { if (config.url.substring(0,responseError: function(response) { switch (response.status) { case 401: var deferred = $q.defer(); if(!inFlightAuthRequest) { inflightAuthRequest = $injector.get("$http").post(API_BASE + '/api/auth/refresh',{refreshtoken: authService.getRefreshToken()}); } inflightAuthRequest.then(function(r) { inflightAuthRequest = null; if (r.data.data.accesstoken && r.data.data.refreshtoken && r.data.data.expiresin) { authService.setAccessToken(r.data.data.accesstoken); authService.setRefreshToken(r.data.data.refreshtoken); authService.setExpiresIn(r.data.data.expiresin); $injector.get("$http")(response.config).then(function(resp) { deferred.resolve(resp); },function(response) { inflightAuthRequest = null; deferred.reject(); authService.clear(); $injector.get("$state").go('guest.login'); return; }); return deferred.promise; break; default: authService.clear(); $injector.get("$state").go('guest.login'); break; } return response || $q.when(response); } }; }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |