Skip to main content
Glama
jwt-auth.guard.ts3.18 kB
import { Injectable, ExecutionContext, UnauthorizedException, Logger, } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Reflector } from '@nestjs/core'; import { Request } from 'express'; import { PUBLIC_KEY } from '../decorators/permissions.decorator'; import { AuthService } from '../services/auth.service'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { private readonly logger = new Logger(JwtAuthGuard.name); constructor( private readonly reflector: Reflector, private readonly authService: AuthService, ) { super(); } async canActivate(context: ExecutionContext): Promise<boolean> { // 检查是否为公共端点 const isPublic = this.reflector.getAllAndOverride<boolean>(PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) { return true; } const request = context.switchToHttp().getRequest<Request>(); try { // 调用父类的 canActivate 方法进行 JWT 验证 const result = await super.canActivate(context); if (!result) { return false; } // 验证用户状态 const user = request.user; if (!user) { throw new UnauthorizedException('用户信息无效'); } // 记录API访问 await this.logApiAccess(request); return true; } catch (error) { this.logger.warn(`JWT认证失败: ${error.message}`, { ip: this.getClientIp(request), userAgent: request.get('User-Agent'), path: request.path, method: request.method, }); throw new UnauthorizedException('认证失败'); } } handleRequest(err: any, user: any, info: any, context: ExecutionContext) { if (err || !user) { const request = context.switchToHttp().getRequest<Request>(); this.logger.warn('JWT认证处理失败', { error: err?.message, info: info?.message, ip: this.getClientIp(request), path: request.path, }); throw err || new UnauthorizedException('认证令牌无效'); } return user; } /** * 记录API访问 */ private async logApiAccess(request: Request): Promise<void> { try { const user = request.user as any; const ipAddress = this.getClientIp(request); const userAgent = request.get('User-Agent') || ''; const path = request.path; const method = request.method; // 记录API访问日志 await this.authService['auditService']?.logApiAccess( user?.id, method, path, 200, // statusCode ipAddress, userAgent, ); } catch (error) { // 记录日志失败不应该影响请求处理 this.logger.error('记录API访问日志失败', error); } } /** * 获取客户端IP地址 */ private getClientIp(request: Request): string { return ( (request.headers['x-forwarded-for'] as string)?.split(',')[0] || (request.headers['x-real-ip'] as string) || request.connection.remoteAddress || request.socket.remoteAddress || '' ); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zaizaizhao/mcp-swagger-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server