Angular 17项目中HTTP Interceptor未生效问题求助
Angular 17中AuthInterceptor的intercept方法未触发的解决方法
问题描述
在Angular 17项目中,AuthInterceptor的intercept方法始终未被调用。流程为:login.component的FormSubmit()方法调用login.service的generateToken()发起HTTP POST请求,但拦截器未在任何HTTP请求执行前触发。
错误原因及修复步骤
1. 清理多余的@NgModule装饰器
Angular 17采用独立组件模式,服务和拦截器无需额外的@NgModule装饰器,多余的装饰器会干扰依赖注入系统。
修改login.service.ts
删除文件中的@NgModule代码块,保留@Injectable({ providedIn: 'root' })即可:
import { Injectable } from '@angular/core'; import baseUrl from './helper'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class LoginService { constructor(private http:HttpClient) { } //get current user public getCurrentUser(){ return this.http.get(`${baseUrl}/current-user`); } //generate token public generateToken(loginData: any) { console.log("genrate Token start"); return this.http.post(`${baseUrl}/generate-token`, loginData); } //login user: set token in local storage public loginUser(token: string) { localStorage.setItem("token_exam_portal", token); return true; } //isLogin: whether user is logged in or not public isLoggedIn() { let tokenStr = localStorage.getItem("token_exam_portal"); if (tokenStr == undefined || tokenStr == '' || tokenStr == null) { return false; } return true; } //logout: remove token_exam_portal from the local storage public logout() { localStorage.removeItem("token_exam_portal"); localStorage.removeItem("user"); return true; } //get token public getToken() { return localStorage.getItem("token_exam_portal"); } //set user deatails public setUser(user: any) { localStorage.setItem('user', JSON.stringify(user)); } //get user public getUser() { let userStr = localStorage.getItem("user"); if (userStr != null) { return JSON.parse(userStr); } else { this.logout(); return null; } } // get user role public getUserRole(){ let user = this.getUser(); return user.authorities[0].authority;// returns only first role } }
修改auth.interceptor.ts
删除文件中的@NgModule代码块,仅保留拦截器类和提供者定义:
import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; import { LoginService } from "./login.service"; const TOKEN_HEADER = 'Authorization'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private login: LoginService) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { //add the jwt token console.log("Executing intercept method"); let authReq = req; const token = this.login.getToken(); if (token != null) { //if token exists then add the token as header to the http request authReq = authReq.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); } return next.handle(authReq); } } export const authInterceptorProviders = { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true, };
2. 全局注册拦截器
拦截器必须在app.config.ts的全局提供者数组中注册,才能被HttpClient识别并触发。
修改app.config.ts
导入拦截器提供者并添加到providers数组:
import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideAnimations } from '@angular/platform-browser/animations'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { authInterceptorProviders } from './services/auth.interceptor'; // 根据实际路径调整 export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideAnimations(), provideHttpClient(withInterceptorsFromDi()), authInterceptorProviders // 全局注册拦截器 ] };
3. 移除组件中重复注册的服务
LoginComponent的providers数组中重复注册了LoginService,而该服务已经通过providedIn: 'root'全局注册,重复注册会导致创建多个实例,可能干扰拦截器逻辑。
修改login.component.ts的@Component配置
移除providers中的LoginService:
@Component({ selector: 'app-login', standalone: true, imports: [MatInputModule, MatFormFieldModule, MatButtonModule, FormsModule,MatSnackBarModule,MatCardModule], providers:[MatSnackBar, UserService, TempService], // 移除LoginService templateUrl: './login.component.html', styleUrl: './login.component.css' })
验证修复
完成上述修改后,重新启动项目,发起登录请求,控制台会输出Executing intercept method,说明拦截器已正常触发。
内容的提问来源于stack exchange,提问作者Vivek Dama
相关产品推荐
相关产品推荐

