| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- 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);
- })
- );
- };
|