refresh token刷新jwt后如何刷新数据
How to refresh data after refresh token refreshes jwt
我已经尝试让我的刷新令牌工作一段时间了,我希望我已经接近了。我的令牌刷新并触发后续 200 调用,无论调用导致 401,但我页面上的数据没有刷新。
当访问令牌过期时,会发生以下情况:
在 401 之后,GetListofCompanyNames returns 200 包含使用正确更新的访问令牌的名称列表。但是,我的下拉菜单没有刷新。
我的拦截器:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
var $http = $injector.get('$http');
return $http(rejection.config);
});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
我的 return 关于 401 拒绝的声明在这里看起来很可疑,但我不确定用什么来替换它。因此我的问题是:当我拨打新电话时,如何让我的页面刷新它的数据?
更新:
这让我在 200 return 秒时过去了,我可以得到一个下拉菜单来刷新,但是我失去了页面上的任何状态(例如选定的下拉菜单)。
authService.refreshToken().then(function() {
var $state = $injector.get('$state');
$state.reload();
});
回到绘图板!
我想你可能想改变你处理这件事的方式。解决此问题的一种方法是将 $rootScope 注入到您的 authInterceptorService
中,然后一旦您成功刷新令牌,就调用 $rootScope.broadcast('tokenRefreshed')
之类的东西。
我不太清楚您是如何设置处理下拉列表的视图和控制器的,但我会为该 'tokenRefreshed'
事件设置一个侦听器。从这里,您可以再次调用 GetListofCompanyNames
。如果您这样做,您可以轻松控制并确保模型得到更新。
尝试在 $timeout
中发出重试呼叫,应该可以。
这是更新后的代码:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
return $timeout(function() {
var $http = $injector.get('$http');
return $http(rejection.config);
}});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
$timeout returns a promise that is completed with what is returned
from the function parameter, so we can conveniently just return the
$http call wrapped in $timeout.
谢谢。
我的最终解决方案:
app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
var $http;
var retryHttpRequest = function(config, deferred) {
$http = $http || $injector.get('$http');
$http(config).then(function(response) {
deferred.resolve(response);
},
function(response) {
deferred.reject(response);
});
}
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
var deferred = $q.defer();
if (rejection.status === 401) {
var authService = $injector.get('authService');
authService.refreshToken().then(function() {
retryHttpRequest(rejection.config, deferred);
},
function () {
authService.logOut();
$location.path('/login');
deferred.reject(rejection);
});
} else {
deferred.reject(rejection);
}
return deferred.promise;
}
};
}
]);
从 https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.Web/app/services/authInterceptorService.js 复制了几乎 1 对 1。
这个透明地处理所有请求并在必要时刷新它们。它会在刷新令牌过期时注销用户,并通过正确拒绝将错误传递给控制器。但是,它似乎不适用于多个飞行请求,当我在我的系统中得到一个用例时,我会研究它。
我已经尝试让我的刷新令牌工作一段时间了,我希望我已经接近了。我的令牌刷新并触发后续 200 调用,无论调用导致 401,但我页面上的数据没有刷新。
当访问令牌过期时,会发生以下情况:
在 401 之后,GetListofCompanyNames returns 200 包含使用正确更新的访问令牌的名称列表。但是,我的下拉菜单没有刷新。
我的拦截器:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
var $http = $injector.get('$http');
return $http(rejection.config);
});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
我的 return 关于 401 拒绝的声明在这里看起来很可疑,但我不确定用什么来替换它。因此我的问题是:当我拨打新电话时,如何让我的页面刷新它的数据?
更新:
这让我在 200 return 秒时过去了,我可以得到一个下拉菜单来刷新,但是我失去了页面上的任何状态(例如选定的下拉菜单)。
authService.refreshToken().then(function() {
var $state = $injector.get('$state');
$state.reload();
});
回到绘图板!
我想你可能想改变你处理这件事的方式。解决此问题的一种方法是将 $rootScope 注入到您的 authInterceptorService
中,然后一旦您成功刷新令牌,就调用 $rootScope.broadcast('tokenRefreshed')
之类的东西。
我不太清楚您是如何设置处理下拉列表的视图和控制器的,但我会为该 'tokenRefreshed'
事件设置一个侦听器。从这里,您可以再次调用 GetListofCompanyNames
。如果您这样做,您可以轻松控制并确保模型得到更新。
尝试在 $timeout
中发出重试呼叫,应该可以。
这是更新后的代码:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
return $timeout(function() {
var $http = $injector.get('$http');
return $http(rejection.config);
}});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
$timeout returns a promise that is completed with what is returned from the function parameter, so we can conveniently just return the $http call wrapped in $timeout.
谢谢。
我的最终解决方案:
app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
var $http;
var retryHttpRequest = function(config, deferred) {
$http = $http || $injector.get('$http');
$http(config).then(function(response) {
deferred.resolve(response);
},
function(response) {
deferred.reject(response);
});
}
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
var deferred = $q.defer();
if (rejection.status === 401) {
var authService = $injector.get('authService');
authService.refreshToken().then(function() {
retryHttpRequest(rejection.config, deferred);
},
function () {
authService.logOut();
$location.path('/login');
deferred.reject(rejection);
});
} else {
deferred.reject(rejection);
}
return deferred.promise;
}
};
}
]);
从 https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.Web/app/services/authInterceptorService.js 复制了几乎 1 对 1。
这个透明地处理所有请求并在必要时刷新它们。它会在刷新令牌过期时注销用户,并通过正确拒绝将错误传递给控制器。但是,它似乎不适用于多个飞行请求,当我在我的系统中得到一个用例时,我会研究它。