Angular 4.3 - HTTP 拦截器 - 刷新 JWT 令牌 [英] Angular 4.3 - HTTP Interceptor - refresh JWT token

查看:14
本文介绍了Angular 4.3 - HTTP 拦截器 - 刷新 JWT 令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要(在拦截器类中)对 403 Forbidden HTTP status(以获取/刷新)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 对象(对错误响应的反应是无用的).事件对象如下所示:{类型: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}.

问题:

-如何正确处理httpErrorResponse(403 Forbidden)中的当我需要刷新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)

只需将授权标头添加到原始请求的副本中

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆