【发布时间】:2022-01-03 21:00:05
【问题描述】:
我正在使用 Angular 13,尝试将 JWT 添加到标头以访问后端的受限路由。在后端检查时,JwtInterceptor 似乎没有修改 HTTP 请求标头。
在我的项目中,我只在根 AppModule 中包含了一次 HttpClientModule。我已将一个带有错误捕获的管道函数附加到我的next 对象(在拦截器内部),以便按照在 SO 上有类似问题的人的建议进行调试,但无济于事,为简洁起见,删除了管道函数。
我已经在文件中像 console.log'ing 一样基本,但没有输出可以解释它,所以我怀疑拦截器根本没有触发。
我以前使用过拦截器,但没有遇到过这个问题,所以我很难过。这里唯一的区别是我正在使用 Angular PWA,如果我理解正确,服务工作者不应该阻碍拦截器的行为吗?我知道 POST 请求会属于“缓存破坏”事件?
也许错误在于 PWA 的实施?在这种情况下,我确实遵循了文档。
附件是 HttpInterceptors 的 App Module、Jwtinterceptor 和“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 },
];
【问题讨论】:
-
嗨。 httpInterceptorProviders 是数组吗? [...httpInterceptorProviders] 试试这个
-
@MohammadBabaei 这是正确的 httpInterceptorProviders 是一个数组。将扩展运算符添加到我的 AppModule 中的提供程序数组中?我试过了,以防万一这就是你的意思,但它仍然失败。抱歉,如果这不是您的意思,也许您可以澄清一下。
-
只是为了确认一下,你可以达到 if 条件,对吗?
-
@DerrickRose 到目前为止,我不相信我会达到 if 条件。我确实有一个
console.log("JWT Interceptor");作为一种非正式的检查方式,但每当我通过网络发送请求时都没有日志。感谢您的回复,如果我可以让该该死的文件注册,我会接受,因为它看起来会起作用并且是迄今为止最全面的回复。 -
@DerrickRose 自从我浏览 SO 以来一直在跟进。接受了您的回复。将我的解决方案贴在您的下方,感谢您的帮助。
标签: angular typescript jwt progressive-web-apps mean-stack