NestJS 中基于角色的访问控制
NestJS 中基于角色的授权
授权是应用程序安全性的一个关键方面。它确保用户只能访问他们被允许访问的资源。在 NestJS(一种渐进式 Node.js 框架)中,由于其模块化设计和对装饰器的支持,实现基于角色的授权非常简单。
什么是基于角色的授权?
基于角色的授权根据用户的角色为其分配权限。常见角色包括“管理员”、“用户”和“访客”。每个角色都有一组可执行的预定义操作。例如:
通过实施基于角色的授权,您可以轻松控制应用程序内的访问。
在 NestJS 中设置基于角色的授权
以下是如何在 NestJS 中实现基于角色的授权:
1.安装依赖项
首先,确保您已设置 NestJS 项目。如果没有,您可以使用 CLI 创建一个:
npm i -g @nestjs/cli nest new my-app
接下来,安装 `@nestjs/passport` 和 `passport` 以支持身份验证:
npm install @nestjs/passport passport passport-jwt npm install --save-dev @types/passport-jwt
2. 定义角色
创建一个“roles.enum.ts”文件来将角色定义为枚举:
export enum Role { Admin = 'admin', User = 'user', Guest = 'guest', }
3. 创建角色守卫
NestJS 中的防护装置会在请求到达路由处理程序之前对其进行拦截。创建自定义防护装置以实施基于角色的访问控制。
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Role } from './roles.enum'; @Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const roles = this.reflector.get('roles', context.getHandler()); if (!roles) { return true; } const request = context.switchToHttp().getRequest(); const user = request.user; return roles.some((role) => user?.roles?.includes(role)); } }
4. 创建角色装饰器
为了简化向路由处理程序添加角色的过程,请创建自定义装饰器:
import { SetMetadata } from '@nestjs/common'; import { Role } from './roles.enum'; export const Roles = (...roles: Role[]) => SetMetadata('roles', roles);
5. 全局或本地应用角色保护
要使“RolesGuard”处于活动状态,您可以全局或本地应用它。对于全局应用,请将其添加到您的“AppModule”中:
import { Module } from '@nestjs/common'; import { APP_GUARD } from '@nestjs/core'; import { RolesGuard } from './roles.guard'; @Module({ providers: [ { provide: APP_GUARD, useClass: RolesGuard, }, ], }) export class AppModule {}
对于本地应用,在特定的控制器或方法中使用它:
import { Controller, Get, UseGuards } from '@nestjs/common'; import { Roles } from './roles.decorator'; import { RolesGuard } from './roles.guard'; import { Role } from './roles.enum'; @Controller('resources') @UseGuards(RolesGuard) export class ResourcesController { @Get() @Roles(Role.Admin, Role.User) findAll() { return 'This endpoint is accessible to Admins and Users.'; } }
6. 验证用户身份
要识别用户的角色,请确保您的身份验证过程将角色添加到请求中的“用户”对象。这通常涉及解码 JWT 或使用会话存储。
身份验证中间件示例
import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class AuthMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { const token = req.headers['authorization']; if (token) { const decoded = this.decodeToken(token); // Implement JWT decoding req.user = decoded; } next(); } private decodeToken(token: string): any { // Logic to decode JWT and retrieve user data return { roles: ['user'] }; // Example decoded payload } }
测试实施
启动您的应用程序并使用不同角色的用户测试端点。确保每个用户只能访问其角色允许的内容。
示例请求
结论
NestJS 中基于角色的授权简洁高效,这得益于装饰器、保护器和框架的模块化。通过遵循上述步骤,您可以保护应用程序的安全,同时保持灵活性和可扩展性。
对于更复杂的场景,请考虑与**Casl**等外部库集成或实现基于属性的访问控制(ABAC)。