【发布时间】:2021-03-16 14:25:25
【问题描述】:
我在我的应用程序中使用拦截器,当令牌过期(返回 401)时,我想刷新令牌,将新令牌保存到 localstorage,然后使用新令牌继续请求。
捕获 401 错误有效,我能够获取新令牌,但请求仍然失败并出现 401 并且不起作用直到我刷新页面。
这是当前使用的拦截方法的代码:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('Interceptor called===============>');
const token = localStorage.getItem(environment.TOKEN_NAME);
if (token) {
const headers = { Authorization: `Bearer ${token}` };
Object.keys(AppHttpInterceptor.headers).forEach((header) => {
// @ts-ignore
if (!AppHttpInterceptor.headers[header]) {
return;
}
// @ts-ignore
headers[header] = AppHttpInterceptor.headers[header];
});
request = request.clone({ setHeaders: headers });
}
const handled: Observable<HttpEvent<any>> = next.handle(request);
const subject: AsyncSubject<HttpEvent<any>> = new AsyncSubject();
handled.subscribe(subject);
subject.subscribe((event: HttpEvent<any>) => {
if (event instanceof HttpErrorResponse) {
if (event.status === 401) {
return;
}
this.httpError.emit(event);
}
}, (err: HttpEvent<any>) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.tokenRefreshService.refreshToken().subscribe(response => {
const headers = { Authorization: `Bearer ${localStorage.getItem(environment.TOKEN_NAME)}` };
console.log('HEADERS ======> ' + headers);
// @ts-ignore
Object.keys(AppHttpInterceptor.headers).forEach((header) => {
// @ts-ignore
if (!AppHttpInterceptor.headers[header]) {
return;
}
// @ts-ignore
headers[header] = AppHttpInterceptor.headers[header];
});
request = request.clone({ setHeaders: headers });
});
return;
}
if (err.status === 404) {
return;
}
this.httpError.emit(err);
}
});
return Observable.create((obs: Observer<HttpEvent<any>>) => {
subject.subscribe(obs);
});
}
这是正确的方法吗?
【问题讨论】:
-
为什么不使用令牌静默刷新?假设您已经获得 401 这不是刷新令牌的最佳方法。此外,订阅 observables 也是不好的做法,如果您愿意,您应该操作流
-
只是为了让您可以一瞥这里:dev-academy.com/angular-jwt我不知道您到底想做什么,但是您很可能想要实现一个逻辑@ 987654324@
-
@LukaszBalazy 感谢您的回复。我查看了静默刷新选项,不幸的是,我的身份验证服务器运行在 Spring Security 之后,我无法将其配置为与 OIDC 一起使用
-
你正在以一种奇怪的方式做这件事。您只需要一些
catchError/retry*运算符,获取一个新令牌并重做请求。在您的拦截器中,您似乎正在执行一些请求分配,但我没有看到它正在执行,然后重新执行原始请求 -
@Sergey 你能提供一个示例代码吗?我发布的代码实际上是跟踪和错误,因此是赏金。
标签: angular jwt access-token angular-http-interceptors