首页 > 解决方案 > 在 Angular 12 中实现刷新令牌

问题描述

在我的服务中,我有获取刷新令牌的请求,如下所示:

  public refreshToken(token: string) {
    return this.http.post<any>(`${this.baseUrl}/auth/token/refresh`, { token }, { headers: this.getAuthorizationHeader() });
  }

这是我的拦截器文件:

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpEvent,
} from '@angular/common/http';
import { Observable, BehaviorSubject, Subject } from 'rxjs';
import { filter, take, switchMap } from 'rxjs/operators';
import { JwtHelperService } from '@auth0/angular-jwt';

import { AuthenticationService } from '../_services';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  private refreshTokenInProgress = false;
  private refreshTokenSubject: Subject<any> = new BehaviorSubject<any>(null);
  private storageKey = 'currentUser';

  constructor(
    private authenticationService: AuthenticationService,
    private jwtHelper: JwtHelperService,
  ) { }

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    if (req.body.operationName === 'refreshToken') {
      return next.handle(req);
    }

    const token = this.jwtHelper.tokenGetter();
    if (token) {
      const tokenData = this.jwtHelper.decodeToken(token);
      const currentDate = new Date();

      if (tokenData.exp < Date.parse(currentDate.toString()) / 1000) {
        if (!this.refreshTokenInProgress) {
          this.refreshTokenInProgress = true;
          this.refreshTokenSubject.next(null);
          return this.authenticationService
            .refreshToken()
            .pipe(
              switchMap((authResponse: any) => {
                const refreshToken = authResponse.data.refreshToken.access_token;
                const stringifyUser = JSON.stringify(tokenData);

                sessionStorage.setItem('token', refreshToken);
                sessionStorage.setItem(this.storageKey, stringifyUser);

                this.refreshTokenInProgress = false;
                this.refreshTokenSubject.next(refreshToken);
                return next.handle(this.addAuthenticationToken(req));
              })
            );
        } else {
          return this.refreshTokenSubject.pipe(
            filter(result => result !== null),
            take(1),
            switchMap((res) => next.handle(this.addAuthenticationToken(req)))
          );
        }
      }
    }

    return next.handle(req);
  }

  addAuthenticationToken(request: HttpRequest<any>) {
    // Get access token
    const token = this.jwtHelper.tokenGetter();

    // If access token is null this means that user is not logged in
    // And we return the original request
    if (!token) {
      return request;
    }

    // We clone the request, because the original request is immutable
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`,
      }
    });
  }
}

问题是,里面的代码switchMap永远不会被执行。

标签: angulartypescript

解决方案


推荐阅读