forked from datawhale/whale-town-end
98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
/**
|
||
* 管理员鉴权守卫
|
||
*
|
||
* 功能描述:
|
||
* - 保护后台管理接口的访问权限
|
||
* - 验证Authorization Bearer Token
|
||
* - 确保只有role=9的管理员可以访问
|
||
*
|
||
* 职责分离:
|
||
* - HTTP请求权限验证
|
||
* - Token解析和验证
|
||
* - 管理员身份确认
|
||
*
|
||
* 主要方法:
|
||
* - canActivate() - 权限验证核心逻辑
|
||
*
|
||
* 使用场景:
|
||
* - 后台管理API的权限保护
|
||
* - 管理员身份验证
|
||
*
|
||
* 最近修改:
|
||
* - 2026-01-08: 注释规范优化 - 为接口添加注释,完善文档说明 (修改者: moyin)
|
||
* - 2026-01-07: 代码规范优化 - 修正文件命名规范,更新作者信息和修改记录
|
||
* - 2026-01-08: 注释规范优化 - 补充方法注释,添加@param、@returns、@throws和@example (修改者: moyin)
|
||
*
|
||
* @author moyin
|
||
* @version 1.0.3
|
||
* @since 2025-12-19
|
||
* @lastModified 2026-01-08
|
||
*/
|
||
|
||
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
|
||
import { Request } from 'express';
|
||
import { AdminCoreService, AdminAuthPayload } from '../../core/admin_core/admin_core.service';
|
||
|
||
/**
|
||
* 管理员请求接口
|
||
*
|
||
* 功能描述:
|
||
* 扩展Express Request接口,添加管理员认证信息
|
||
*
|
||
* 使用场景:
|
||
* - AdminGuard验证通过后,将管理员信息附加到请求对象
|
||
* - 控制器方法中获取当前管理员信息
|
||
*/
|
||
export interface AdminRequest extends Request {
|
||
admin?: AdminAuthPayload;
|
||
}
|
||
|
||
@Injectable()
|
||
export class AdminGuard implements CanActivate {
|
||
constructor(private readonly adminCoreService: AdminCoreService) {}
|
||
|
||
/**
|
||
* 权限验证核心逻辑
|
||
*
|
||
* 功能描述:
|
||
* 验证HTTP请求的Authorization头,确保只有管理员可以访问
|
||
*
|
||
* 业务逻辑:
|
||
* 1. 提取Authorization头
|
||
* 2. 验证Bearer Token格式
|
||
* 3. 调用核心服务验证Token
|
||
* 4. 将管理员信息附加到请求对象
|
||
*
|
||
* @param context 执行上下文,包含HTTP请求信息
|
||
* @returns 是否允许访问,true表示允许
|
||
*
|
||
* @throws UnauthorizedException 当缺少Authorization头或格式错误时
|
||
* @throws UnauthorizedException 当Token无效或过期时
|
||
*
|
||
* @example
|
||
* ```typescript
|
||
* // 在控制器方法上使用
|
||
* @UseGuards(AdminGuard)
|
||
* @Get('users')
|
||
* async getUsers() { ... }
|
||
* ```
|
||
*/
|
||
canActivate(context: ExecutionContext): boolean {
|
||
const req = context.switchToHttp().getRequest<AdminRequest>();
|
||
const auth = req.headers['authorization'];
|
||
|
||
if (!auth || Array.isArray(auth)) {
|
||
throw new UnauthorizedException('缺少Authorization头');
|
||
}
|
||
|
||
const [scheme, token] = auth.split(' ');
|
||
if (scheme !== 'Bearer' || !token) {
|
||
throw new UnauthorizedException('Authorization格式错误');
|
||
}
|
||
|
||
const payload = this.adminCoreService.verifyToken(token);
|
||
req.admin = payload;
|
||
return true;
|
||
}
|
||
}
|