Angular 4.3-HTTP拦截器-刷新JWT令牌 [英] Angular 4.3 - HTTP Interceptor - refresh JWT token
问题描述
我需要(在拦截器类中)对403禁止的HTTP状态(以获取/刷新)JWT令牌做出反应,并使用新令牌重试该请求.
I need to react (in interceptor class) on 403 Forbidden HTTP status (to obtain/refresh) JWT token and retry the request with fresh token.
在下面的代码中,当服务器返回错误响应时,它将转到成功回调(不像我期望的那样进入错误回调),并且该事件是typeof对象(对错误响应的响应没有用).事件对象如下所示: {type:0}.
In the code below, when server return error response it goes to success callback (not into the error callback as I expect) and the event is typeof object (which is useless in reaction on error response). The event object looks like this: {type:0}.
问题:
-如何正确处理 当我需要刷新accessToken并重试http请求时,使用HttpInterceptor?
-How to properly handle httpErrorResponse (403 Forbidden) in HttpInterceptor when I need refresh accessToken and retry the http request?
import {
HttpInterceptor,
HttpRequest,
HttpResponse,
HttpHandler,
HttpEvent
} from '@angular/common/http';
import 'rxjs/add/operator/map';
@Injectable()
class JWTInterceptor implements HttpInterceptor {
constructor(private tokenService: TokenService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let myHeaders = req.headers;
if (this.tokenService.accessToken) {
myHeaders = myHeaders.append('Authorization',`${this.tokenService.accessToken.token_type} ${this.tokenService.accessToken.access_token}`)
}
const authReq = req.clone({headers: myHeaders});
return next.handle(authReq).map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// success callback
}
}, (err: any) => {
if (err instanceof HttpErrorResponse {
if (err.status === 403) {
// error callback
this.tokenService.obtainAccessToken()
}
}
})
.retry(1);
}
}
推荐答案
我对这个问题的最终解决方案:
My final solution to this problem:
@Injectable()
export class WebApiInterceptor implements HttpInterceptor {
constructor(private tokenService: TokenService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('*An intercepted httpRequest*', req, this.tokenService.accessToken);
const authReq = this.authenticateRequest(req);
console.log('*Updated httpRequest*', authReq);
return next.handle(authReq)
.map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('*An intercepted httpResponse*', event);
return event;
}
})
.catch((error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 403 && error.url !== environment.authEndpoint) {
return this.tokenService
.obtainAccessToken()
.flatMap((token) => {
const authReqRepeat = this.authenticateRequest(req);
console.log('*Repeating httpRequest*', authReqRepeat);
return next.handle(authReqRepeat);
});
}
} else {
return Observable.throw(error);
}
})
}
}
功能
authenticateRequest(req)
只需将Authorization标头添加到原始请求的副本中
just adds Authorization header to the copy of original request
功能
obtainAccessToken()
获取新令牌形式授权服务器并将其存储
get fresh token form authorization server and stores it
这篇关于Angular 4.3-HTTP拦截器-刷新JWT令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!