Angular HTTP 拦截器不修改 HTTP 请求 headers

Angular HTTP interceptor not modifying HTTP request headers

我正在使用 Angular 13,试图将 JWT 添加到 headers 以访问后端的受限路由。后端检查 JwtInterceptor 似乎没有修改 HTTP 请求 headers。 我只在我的项目中包含了一次 HttpClientModule,在根 AppModule 中。我在我的 next object (拦截器内部)附加了一个管道函数,以便按照在 SO 上有类似问题的人的建议进行调试,但无济于事,删除了管道函数简洁。

我已经在文件中进行了 console.log 的基本操作,但是没有输出来解释它,所以我怀疑拦截器根本没有触发。

我以前使用过拦截器,但没有遇到过这个问题,所以我很困惑。这里唯一的区别是我正在使用 Angular PWA,如果我理解正确的话,service worker 不应该阻碍拦截器的行为?我知道 POST 请求属于“缓存破坏”事件?

可能是PWA实现的错误?在这种情况下,我确实遵循了文档。

附件是应用程序模块、Jwtinterceptor 和 HttpInterceptors 的“Barrel”,我计划向项目添加更多拦截器,所以我按照文档建议创建了 Barrel。

TL;DR
我的 HttpInterceptor (JwtInterceptor) 似乎根本没有触发。这个实现在过去的项目中对我有用,唯一的区别是这个项目是一个 PWA。不确定这是否与 PWA 实施有冲突或怪癖。 HttpClientModule 在项目中只包含一次。

app.module.ts

//Angular level imports
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

//App level components
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { HeaderComponent } from './header/header.component';
import { AngularMaterialModule } from './_material/material.module';
import { UploadDirective } from './directives/upload.directive';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { ThanksComponent } from './thanks/thanks.component';
import { PhotoAlbumsComponent } from './photo-albums/photo-albums.component';
import { DialogComponent } from './dialog/dialog.component';
import { AlbumComponent } from './album/album.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { ForgotPasswordComponent } from './forgot-password/forgot-password.component';
import { ResetPasswordComponent } from './reset-password/reset-password.component';
import { ThanksBotDownloadComponent } from './thanks-bot-download/thanks-bot-download.component';
import { ErrorBotDownloadComponent } from './error-bot-download/error-bot-download.component';
import { RouterModule } from '@angular/router';
import { httpInterceptorProviders } from './_interceptors/index';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    HeaderComponent,
    UploadDirective,
    LoginComponent,
    RegisterComponent,
    ThanksComponent,
    PhotoAlbumsComponent,
    AlbumComponent,
    DialogComponent,
    ForgotPasswordComponent,
    ResetPasswordComponent,
    ThanksBotDownloadComponent,
    ErrorBotDownloadComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    AngularMaterialModule,
    ServiceWorkerModule.register('ngsw-worker.js', {
      enabled: environment.production,
      // Register the ServiceWorker as soon as the app is stable
      // or after 30 seconds (whichever comes first).
      registrationStrategy: 'registerWhenStable:30000',
    }),
    HttpClientModule,
    RouterModule,
  ],
  providers: [httpInterceptorProviders],
  bootstrap: [AppComponent],
})
export class AppModule {}

jwt.interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { environment } from '@environments/environment';
import { AccountService } from '@app/_services/account.service';


@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  constructor(private accountService: AccountService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // add auth header with jwt if user is logged in and request is to the api url
    //console.log("JWT Interceptor");
    const user = this.accountService.currentUserValue;
    const isLoggedIn = user && user.jwt;
    const isApiUrl = request.url.startsWith(environment.apiUrl);
    if (isLoggedIn && isApiUrl) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${user.jwt}`,
        },
      });
    }

    return next.handle(request);
  }
}

index.ts“桶”文件

/* "Barrel" of Http interceptors */
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { JwtInterceptor } from './jwt.interceptor';

/* Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
];

Post请求Headers

而不是 setHeaders 试试 headers.

request = req.clone({
    headers: req.headers.append('Authorization', `Bearer ${user.jwt}`)
});

虽然看起来这个问题是因为你的条件不满足造成的。

感谢帮助过的人

这个问题与将我的应用程序转换为 PWA 有关。服务工作者正在影响我的令牌拦截器。我 re-did 我的应用程序没有 PWA,并且按预期工作。因此,如果您的拦截器停止工作,请务必小心 post service worker 实现,它可能实际上不是您的拦截器。

我会建议任何拥有可运行的应用程序并有兴趣将其转换为 PWA 的人阅读文档,但要遵循更全面的教程,因为我确实觉得 Angular 文档用于更高级的主题凭空写成,缺少上下文。