import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import { Request } from 'express'; import { IS_PUBLIC_KEY } from '../decorators/public.decorator'; @Injectable() export class JwtAuthGuard implements CanActivate { constructor( private readonly jwtService: JwtService, private readonly configService: ConfigService, private readonly reflector: Reflector, ) {} async canActivate(context: ExecutionContext): Promise { const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) return true; const request = context.switchToHttp().getRequest(); const token = this.extractToken(request); if (!token) { throw new UnauthorizedException('请先登录'); } try { const payload = await this.jwtService.verifyAsync(token, { secret: this.configService.get('jwt.secret'), }); request.user = { id: String(payload.sub), email: payload.email, role: payload.role }; return true; } catch { throw new UnauthorizedException('登录已过期,请重新登录'); } } private extractToken(request: Request): string | undefined { const authHeader = request.headers.authorization; if (!authHeader?.startsWith('Bearer ')) return undefined; return authHeader.split(' ')[1]; } }