我有一个基于令牌的身份验证机制的API . 成功登录后,我在浏览器的本地存储中存储了两个令牌 - 访问和刷新令牌 . 访问令牌包含在服务器端授权用户所需的所有必要信息,并且它具有到期日期 . 当访问令牌过期时,客户端可以使用刷新令牌请求新的访问令牌,并且在响应中它将获得一对新令牌 .
在角度1.x中,实现非常简单明了 . 例如,我们可以使用拦截器:
httpInterceptor.$inject = ['$httpProvider'];
function httpInterceptor($httpProvider) {
$httpProvider.interceptors.push(handleStaleAccessToken);
handleStaleAccessToken.$inject = ['$q', '$injector', 'session'];
function handleStaleAccessToken($q, $injector, session) {
function logoutAndRedirect() {
var authenticationRedirect = $injector.get('authenticationRedirect');
session.destroy();
authenticationRedirect.toLoginPage();
}
return {
responseError: function(rejection) {
// Do nothing for non 403 errors
if (rejection.status !== 403) {
return $q.reject(rejection);
}
var errorCode = rejection.data.error && rejection.data.error.code;
if (errorCode === 'access_token_expired') {
var $http = $injector.get('$http');
// Refresh token
var params = { refreshToken: session.getRefreshToken() };
return $http.post('/api/auth/refresh', params).then(function(response) {
session.setTokens(response.data);
// Re try failed http request
return $http(rejection.config);
}).catch(function(error) {
logoutAndRedirect();
return $q.reject(error);
});
} else {
logoutAndRedirect();
}
return $q.reject(rejection);
}
};
}
}
但是如何在angular 2 / rxjs应用程序中实现类似的逻辑?
2 回答
这可以通过扩展
Http
类并利用flatMap
之类的可观察运算符在Angular2中透明地完成 .以下是一些示例代码:
此代码必须集成到
Http
的自定义子类中:一种方法可以是扩展HTTP对象以拦截错误:
并按如下所述注册:
有关详细信息,请查看以下问题:
Handling refresh tokens using rxjs
Angular 2 - How to get Observable.throw globally
在我最近的项目中,我不得不做类似的事情shafihuzaib/cdp-ng-boilerplate并在这个问题上找到答案 . 我无法寻求上述建议的解决方案,因为它感觉很复杂而且不可取 . 所以我在实施之后回来留下我的解决方案 . 然而,不同的是,在我的情况下,我有两个这样的令牌 .
因此,每个需要检查令牌有效性的请求都会在此函数中调用 .
这里最重要的是
func()
应该返回Observable
,以便可以相应地使用它 .对于一个新人来说,这似乎有点复杂,但我相信它会更有效率 .
在以下链接中,请忽略与此问题无关的详细信息,并关注建议的解决方案的使用 .
Actual implementation of tokenValidatedRequest() in my project .
How it is used in other services!
How I finally subscribe to it!