【问题标题】:angular 8 refresh token using interceptor使用拦截器的角度 8 刷新令牌
【发布时间】:2020-10-12 20:03:29
【问题描述】:

我正在尝试使用角度拦截器实现刷新令牌功能。这是我正在遵循的逐步过程

  1. 将访问令牌存储在本地存储中。将此令牌添加到授权标头中。

  2. 如果访问令牌过期,则发送刷新令牌(存储在数据库中)并生成新令牌。

在下面的代码中,我正在尝试实现相同的功能。但问题是当访问令牌过期时,当前的 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


【解决方案1】:

你可以像这样使用 s.th:

getposts() {
return this.http.post<any>(`${config.apiUrl}/post`, {
  'type': 1
}).pipe(
  tap(() => this.doLogoutUser()),
  mapTo(true),
  catchError(error => {
    if(error.status===401){
    return this.http.post<any>(`${config.apiUrl}/post`, {
  'type': 1
     });
    }
  }));
}

还添加 tis 行来捕获拦截器的错误以抛出错误:

return throwError(errorMessage);

这样您就可以在不重新加载页面的情况下重试发送 http.post 的捕获错误的请求

【讨论】:

    猜你喜欢
    • 2019-07-09
    • 2020-05-12
    • 1970-01-01
    • 2020-02-10
    • 2020-02-17
    • 1970-01-01
    • 2022-11-03
    • 2017-02-25
    • 2021-07-30
    相关资源
    最近更新 更多