import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, Logger, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Request } from 'express'; import { UsersService } from '../../users/users.service'; @Injectable() export class AuthGuard implements CanActivate { private readonly logger = new Logger(AuthGuard.name); constructor( private configService: ConfigService, private usersService: UsersService, ) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); // 检查是否启用 Basic Auth const enableBasicAuth = this.configService.get('ENABLE_BASIC_AUTH') === 'true'; this.logger.log(`Basic Auth enabled: ${enableBasicAuth}`); if (!enableBasicAuth) { // 如果未启用 Basic Auth,允许所有访问 return true; } // 解析 Authorization header const authHeader = request.headers['authorization'] as string; if (!authHeader || !authHeader.startsWith('Basic ')) { this.logger.warn('Missing or invalid Authorization header'); throw new UnauthorizedException('Missing or invalid Authorization header'); } // 解码 Basic Auth const base64Credentials = authHeader.split(' ')[1]; const credentials = Buffer.from(base64Credentials, 'base64').toString( 'utf-8', ); const [username, password] = credentials.split(':'); if (!username || !password) { this.logger.warn('Invalid credentials format'); throw new UnauthorizedException('Invalid credentials format'); } this.logger.log(`Attempting login for user: ${username}`); // 验证用户 const user = await this.usersService.validateUser(username, password); if (!user) { this.logger.warn(`Login failed for user: ${username} - Invalid username or password`); throw new UnauthorizedException('Invalid username or password'); } this.logger.log(`User ${username} logged in successfully`); // 将用户信息附加到请求对象 (request as any).user = user; return true; } }