我需要点击一个按钮将我的数据提交给api服务器。同时,我需要检查令牌是否已过期?如果它已过期,系统将自动刷新新令牌并存储到localstorage中。
检查过期令牌并自动续订令牌的方式:
@Injectable()
export class AuthErrorHandler implements ErrorHandler {
constructor(private injector: Injector, private loginService: LoginService) {}
handleError(error) {
if (error.rejection.status === 401 || error.rejection.status === 403) {
this.loginService.postLogin(localStorage.getItem('user_email'), localStorage.getItem('password')).subscribe(res => {
if (res.access_token) {
localStorage.setItem('access_token', res.access_token);
} else if (res.error) {
this.injector.get(Router).navigate(['/login']);
}
}, () => {
this.injector.get(Router).navigate(['/login']);
},
);
}
throw error;
}
}
所以现在问题是我单击按钮并检查过期的令牌并成功刷新但我需要再次单击该按钮。有没有办法可以在不再点击按钮的情况下继续操作?
答案 0 :(得分:0)
我解决这个问题的方式: - 为休息调用创建一个包装类。我叫做AuthService。 - 而不是调用httpclient.get,我调用authservice.get(在检查授权后,它自己调用httpclient.get)
authservice包含一个方法' checkAuth'它检查用户是否已登录并返回一些回调。一般的想法是传递回调。
伪代码(可能):
// Component
click() {
this.authService.get('').subscribe(data => console.log('yay'))
}
// AuthService
get(url: string): Observable<any> {
return this.checkAuth(function() {
return this.http.get(url)
}
}
// AuthService checkAuth
checkAuth(callback: any): Observable<any> {
return new Observable(observer => {
this.isLoggedIn().subscribe(success => {
if (success) {
callback().subscribe(response => {
observer.next(response);
}, error => {
observer.error(error);
});
}
}
}
}
// AuthService isLoggedIn
isLoggedIn(): Observable<boolean> {
return new Observable(observer => {
// Check your authorization and refresh if needed
if (localStorage bla bla) {
this.http.post(refresh etc.etc.)
}
// Do whatever and call observer.next(true || false) or observer.error() depending how you handle the isLoggedIn Observable
}
}
我希望你明白这个想法
答案 1 :(得分:0)
您可以使用拦截器检查您的令牌是否已过期。
如果拦截器从后端检索登录错误,则使用BehaviourSubject续订令牌并保持其余请求暂停,直到您再次登录为止。
使用这种方法,您可以避免多次按下该按钮,并且用户不会知道引擎盖下发生了什么。
此外,我无法发表评论,这也是我将其添加为答案的原因。