You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:45:59