import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http'; import { inject } from '@angular/core'; import { Router } from '@angular/router'; import { catchError, throwError } from 'rxjs'; import { AuthService } from '../services/auth.service'; // 防重复重定向机制 let lastRedirectTime = 0; const REDIRECT_DEBOUNCE_MS = 1000; export const AuthInterceptor: HttpInterceptorFn = (req, next) => { const router = inject(Router); const authService = inject(AuthService); console.log(`拦截请求: ${req.method} ${req.url}`); // 克隆请求以添加认证头 let authReq = req; // 检查是否为公开端点(不需要认证) const isPublicEndpoint = req.url.includes('/auth/login') || req.url.includes('/auth/health'); // 为需要认证的API请求添加Bearer认证头 if (req.url.includes('/api/') && !isPublicEndpoint) { const token = authService.getAuthToken(); console.log(`🔍 [AuthInterceptor] 处理API请求: ${req.method} ${req.url}`); console.log(`🔍 [AuthInterceptor] Token存在: ${!!token}, 长度: ${token?.length}`); if (token) { console.log('🔍 [AuthInterceptor] API请求,添加Bearer认证头'); authReq = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); console.log(`🔍 [AuthInterceptor] 添加后的请求头:`, authReq.headers.get('Authorization')?.substring(0, 30) + '...'); } else { console.warn('🔍 [AuthInterceptor] API请求需要认证,但用户未登录,不添加认证头'); // 不添加认证头,后端会返回401错误,错误处理会跳转到登录页 } } else { console.log('🔍 [AuthInterceptor] 公开端点或非API请求,不添加认证头'); } return next(authReq).pipe( catchError((error: HttpErrorResponse) => { console.log(`请求错误: ${error.status} ${req.method} ${req.url}`); console.log('错误详情:', error.error); // 处理认证错误 if (error.status === 401 || error.status === 403 || (error.error && (error.error.error?.includes('认证') || error.error.error?.includes('缺少认证')))) { console.warn('认证失败,跳转到登录页面:', error.error); console.log('当前路由:', router.url); // 清除本地存储的认证信息 authService.logout(); // 跳转到登录页面,除非当前已经在登录页面 if (!router.url.includes('/login')) { // 防重复重定向:检查上次重定向时间 const now = Date.now(); if (now - lastRedirectTime > REDIRECT_DEBOUNCE_MS) { lastRedirectTime = now; console.log('重定向到登录页面'); router.navigate(['/login'], { queryParams: { returnUrl: router.url } }); } else { console.log('跳过重复重定向(防抖期内)'); } } else { console.log('已经在登录页面,不重定向'); } } return throwError(() => error); }) ); };