【发布时间】:2020-10-12 20:03:29
【问题描述】:
我正在尝试使用角度拦截器实现刷新令牌功能。这是我正在遵循的逐步过程
-
将访问令牌存储在本地存储中。将此令牌添加到授权标头中。
-
如果访问令牌过期,则发送刷新令牌(存储在数据库中)并生成新令牌。
在下面的代码中,我正在尝试实现相同的功能。但问题是当访问令牌过期时,当前的 HTTP 请求没有被执行(给出 401 错误)。我必须重新加载该页面才能使该 HTTP 请求正常工作。我怎样才能避免这种情况?
interceptor.ts
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private router: Router, private loginService: LoginService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const jwt = localStorage.getItem('token')
if (jwt) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${jwt}`
}
});
}
if (!request.headers.has('Content-Type')) {
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
}
return next.handle(request)
.pipe(
retry(1),
catchError((error: HttpErrorResponse) => {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// client-side error
errorMessage = `${error.error.message}`;
} else {
// console.log(error)
switch (error.status) {
case 401: {
console.log(error.error.error.message)
console.log(error)
if (error.error.error.message.includes('jwt expired')) {
console.log(true)
this.handle401Error(request, next)
}
else {
console.log(false)
this.router.navigate(['login'])
}
}
default:
//window.alert(error.error.error.message)
return throwError(error);
}
// server-side error
// errorMessage = `${error.status}\n ${error.message}`;
}
//\ window.alert(errorMessage);
// return throwError(errorMessage);
})
)
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
console.log('refresh token')
const refreshToken = localStorage.getItem('refreshtoken')
console.log(refreshToken)
this.loginService.refresh_token(refreshToken)
.pipe(untilDestroyed(this))
.subscribe(data => {
console.log(data)
localStorage.setItem('token', data.accessToken)
const jwt = localStorage.getItem('token')
console.log('401', jwt)
if(jwt) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${jwt}`
}
});
}
if (!request.headers.has('Content-Type')) {
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
}
return next.handle(request);
})
}
}
【问题讨论】:
-
我不明白为什么你们总是想自己实现所有这些东西。您是否考虑过使用
angular-oauth2-oidc?它甚至允许您执行静默刷新方法。
标签: angular jwt angular8 angular-http-interceptors