如何为传出请求添加 NestJS 拦截器?

问题描述 投票:0回答:1

我正在创建一个 NestJS 应用程序,充当此 API 和其他内容之间的中间件。我需要它来发送带有不记名令牌的每个请求。如果令牌被拒绝,我希望它获取新令牌并再次重试相同的请求。

我正在使用拦截器,这里的基础知识似乎很简单,我只需将令牌添加到请求标头中即可。但是,其他服务始终返回“403 禁止”错误。当我进一步检查时,似乎

Authorization
标头实际上并未添加到请求中!

这是简化版本

intercept(context: ExecutionContext, next: CallHandler) {
  const request = context.switchToHttp().getRequest<Request>();
  request.headers.Authorization = this.token;
  return next.handle();
}

这不是添加

Authorization
标头的正确方法吗?

这是我完整的拦截器代码

@Injectable()
export class AuthTokenInterceptor implements NestInterceptor {
  private readonly authUrl = "https://...";
  private token = "";

  constructor(private readonly http: HttpService) {
    //Get the token as soon as possible
    this.trySaveToken();
  }

  intercept(context: ExecutionContext, next: CallHandler) {
    const request = context.switchToHttp().getRequest<Request>();

    if (!request.headers.Authorization) {
      request.headers.Authorization = this.token;
    }

    return next.handle().pipe(
      catchError((error: AxiosError) => {
        const originalRequest = error.config;

        console.log(originalRequest?.headers); //this has no `Authorization` header on it!

        //If we have an auth error, we probably just need to re-fetch the token
        if (error.response?.status === 401 && originalRequest != null && originalRequest.url !== this.authUrl) {
          //without second check, we can loop forever
          this.trySaveToken();
          originalRequest.headers.Authorization = this.token; //override old default for this request
          return of(originalRequest); //retry request with newly added
        } else {
          return throwError(() => error);
        }
      }),
  }

  private trySaveToken() {
    this.http.post(this.authUrl).subscribe({
      next: (response) => {
        this.token = 'Bearer ' + response.data.access_token;
      },
    });
  }
}

我的重试逻辑可能还不正确,但在我首先解决第一个授权问题之前我无法真正解决这个问题

这是

console.log
产生的结果

Object [AxiosHeaders] {
  Accept: 'application/json, text/plain, */*',    
  'Content-Type': 'application/json',
  'User-Agent': 'axios/1.6.8',
  'Content-Length': '162',
  'Accept-Encoding': 'gzip, compress, deflate, br'
}
nestjs nestjs-interceptor
1个回答
0
投票

事实证明我需要像这样设置

Authorization
标题

this.http.axiosRef.defaults.headers.common.Authorization = this.token;

我不完全明白为什么我必须这样做,但它确实有效

© www.soinside.com 2019 - 2024. All rights reserved.