我正在创建一个 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'
}
事实证明我需要像这样设置
Authorization
标题
this.http.axiosRef.defaults.headers.common.Authorization = this.token;
我不完全明白为什么我必须这样做,但它确实有效