21-11 重要PolicyGuard具体实现逻辑
扩展后的课程大纲:PolicyGuard实现逻辑
【知识点1:PolicyGuard基础结构与依赖注入】
难度:中级 ⭐⭐
时长:8分钟
- 核心逻辑复用
- 从
role permissions
模块复制以下内容:- 权限校验逻辑
- 角色绑定机制
- 策略加载流程
- 从
- 关键模块导入
import { Reflector } from '@nestjs/core'; // 用于元数据反射 import { PermissionService, RoleService } from '@/services'; // 核心服务
typescript - 超级管理员豁免机制
- 配置
.env
文件:SUPER_ADMIN_ROLES=1,2,3
dotenv - 实现逻辑:
if (whiteListRoles.includes(user.roleId)) return true;
typescript
- 配置
- 模块导出规范
- 常见错误:未导出
PermissionService
导致注入失败 - 正确示例:
@Module({ providers: [PermissionService], exports: [PermissionService] // 必须显式导出 })
typescript
- 常见错误:未导出
💡 提示:使用@Global()
装饰器可避免多模块重复导入。
【知识点2:权限策略查询机制】
难度:高级 ⭐⭐⭐
时长:12分钟
- 权限标识动态获取
- 使用
Reflector
从控制器方法读取元数据:const right = this.reflector.get<string>('permission', context.getHandler());
typescript
- 使用
- 策略查询优化
- 问题:原生
find
方法仅支持ID查询 - 解决方案:扩展
findByName
方法async findByName(name: string) { return this.prisma.permission.findUnique({ where: { name }, include: { policies: { include: { policy: true } // 嵌套加载策略详情 } } }); }
typescript
- 问题:原生
- 调试技巧
- 打印权限标识和策略数据:
console.log('Current Right:', right); console.log('Matched Policies:', permissionPolicies);
typescript
- 打印权限标识和策略数据:
💡 提示:使用Prisma Client
的log
参数可输出SQL查询日志。
【知识点3:用户数据与角色策略关联】
难度:高级 ⭐⭐⭐
时长:15分钟
- 用户查询优化
- 关键点:必须包含角色数据以避免后续查询失败
include: { roles: true } // 关联查询用户角色
typescript
- 关键点:必须包含角色数据以避免后续查询失败
- 角色策略批量查询
- 性能优化:使用
findAllByIds
替代循环单条查询const rolePolicies = await this.roleService.findAllByIds(roleIds);
typescript
- 性能优化:使用
- 字段命名规范
- 错误示例:混用
permission
和Permission
导致字段匹配失败 - 解决方案:全项目统一使用
Permission
(首字母大写)。
- 错误示例:混用
【知识点4:策略过滤与权限能力构建】
难度:专家级 ⭐⭐⭐⭐
时长:18分钟
- 策略过滤逻辑
- 核心代码:
const filteredPolicies = rolePolicies.reduce((acc, current) => { const validPolicies = current.policies.filter(policy => subjects.includes(policy.subject) ); return [...acc, ...validPolicies]; }, []);
typescript
- 核心代码:
- 权限能力实例化
- 集成CASL:
const ability = new Ability([ ...permissionPolicies.rules, ...filteredPolicies.rules ]);
typescript
- 集成CASL:
- 动态权限测试
- 测试用例:
场景 预期结果 用户拥有 user:read
返回用户数据 用户无权限 抛出 ForbiddenException
- 测试用例:
【知识点5:调试与数据验证】
难度:中级 ⭐⭐
时长:10分钟
- 调试节点
- 权限标识验证:
console.log('Right:', right)
- 策略数据检查:
console.log('Permission Policies:', permissionPolicies)
- 权限标识验证:
- 自动化测试脚本
describe('PolicyGuard', () => { it('should allow super admin', async () => { const result = await guard.canActivate(mockSuperAdminContext); expect(result).toBe(true); }); });
typescript
附录:深度扩展内容
1. 性能优化建议
- 缓存策略:使用
Redis
缓存高频权限数据 - 批量查询:合并数据库查询减少IO开销
2. 安全增强
- JWT校验:在Guard中集成JWT验证
- 日志审计:记录所有权限校验失败事件
3. 前沿技术动态
- CASL v6:支持动态策略实时加载
- NestJS v10:优化了
Reflector
的性能
4. 延伸学习资源
💡 提示:使用mermaid
绘制权限校验流程图可帮助理解复杂逻辑。
↑