使用NestJS开发安全API:角色管理 - Auth0
使用NestJS开发安全API:角色管理
在现代基于角色的访问控制(RBAC),以确保API的安全性和灵活性。
开始之前的准备工作
在开始之前,请确保您已经完成以下步骤:
-
克隆项目仓库并切换到指定分支:
git clone git@github.com:auth0-blog/wab-menu-api-nestjs.git nest-restaurant-api --branch adding-authorization-auth0 -
将项目文件夹设置为当前目录,并安装所需依赖项。
-
如果尚未设置Auth0应用程序,请参考前面的章节完成相关配置。
-
创建一个
.env文件,并填入以下内容:PORT=7000 AUTH0_ISSUER_URL="Your Auth0 domain" AUTH0_AUDIENCE="Your Auth0 audience"
完成以上步骤后,您即可开始配置基于角色的访问控制。
使用Auth0实现基于角色的访问控制
RBAC是一种根据用户角色分配权限的授权策略。在本教程中,我们将创建一个“菜单管理员”角色,并为其分配特定权限。以下是实现步骤:
1. 创建API权限
在Auth0仪表板中,进入您创建的“菜单API”页面,完成以下操作:
- 点击“权限”选项卡,添加以下权限:
create:itemsupdate:itemsdelete:items
接着,进入“设置”选项卡,启用以下选项:
- 启用RBAC:强制执行基于角色的访问控制。
- 在访问令牌中添加权限:将权限声明添加到JWT令牌中。
完成后,点击“保存”。
2. 创建角色并分配权限
- 在Auth0仪表板中,创建一个名为“菜单管理员”的角色。
- 为该角色分配之前创建的权限:
- 进入角色页面的“权限”选项卡。
- 选择“菜单API”,并添加所有相关权限。
3. 创建管理员用户
- 在Auth0仪表板中,创建一个新用户,例如
admin@example.com。 - 为该用户分配“菜单管理员”角色。
在令牌中添加用户角色
为了让客户端应用程序能够识别用户角色,我们需要使用Auth0规则将角色信息添加到JWT令牌中。
什么是Auth0规则?
Auth0规则是当用户登录时执行的JavaScript函数。您可以使用规则自定义和扩展Auth0的功能。
创建规则
- 在Auth0仪表板中,进入“规则”页面并点击“创建规则”。
- 选择“空规则”,并命名为“向令牌添加用户角色”。
- 替换脚本内容为以下代码:
function(user, context, callback) { const namespace = 'https://menu-api.demo.com'; if (context.authorization && context.authorization.roles) { const assignedRoles = context.authorization.roles; if (context.idToken) { context.idToken[${namespace}/roles] = assignedRoles; } if (context.accessToken) { context.accessToken[${namespace}/roles] = assignedRoles; } } callback(null, user, context); }
此规则会在用户登录时,将其角色信息附加到ID令牌和访问令牌中。
在NestJS中实现基于角色的访问控制
为了在NestJS中实现RBAC,我们将创建一个自定义装饰器和保护器,用于验证用户是否具有访问特定端点的权限。
1. 创建自定义装饰器
运行以下命令创建装饰器文件:
nest generate decorator permissions --no-spec
在permissions.decorator.ts文件中添加以下代码:
import { SetMetadata } from '@nestjs/common';
export const Permissions = (...permissions: string[]) =>
SetMetadata('permissions', permissions);
该装饰器会将权限元数据附加到路由处理程序中。
2. 创建自定义保护器
运行以下命令创建保护器文件:
nest generate guard permissions --no-spec
在permissions.guard.ts文件中添加以下代码:
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class PermissionsGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {} canActivate(context: ExecutionContext): boolean {
const routePermissions = this.reflector.get(
'permissions',
context.getHandler(),
);
if (!routePermissions) {
return true;
} const request = context.switchToHttp().getRequest();
const userPermissions = request.user.permissions; return routePermissions.every(permission =>
userPermissions.includes(permission),
);
}
}
3. 集成到路由中
打开items.controller.ts文件,更新路由处理程序如下:
import { Controller, Get, Post, Put, Delete, Body, Param, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Permissions } from '../permissions.decorator';
import { PermissionsGuard } from '../permissions.guard';
@Controller('items')
export class ItemsController {
@UseGuards(AuthGuard('jwt'), PermissionsGuard)
@Post()
@Permissions('create:items')
create(@Body('item') item: any) {
// 创建逻辑
} @UseGuards(AuthGuard('jwt'), PermissionsGuard)
@Put()
@Permissions('update:items')
update(@Body('item') item: any) {
// 更新逻辑
} @UseGuards(AuthGuard('jwt'), PermissionsGuard)
@Delete(':id')
@Permissions('delete:items')
delete(@Param('id') id: number) {
// 删除逻辑
}
}
通过为路由添加@Permissions装饰器和PermissionsGuard保护器,您可以确保只有拥有相应权限的用户才能访问这些端点。
测试RBAC功能
使用非管理员用户测试
-
登录非管理员账户。
-
使用以下命令尝试创建新项目:
curl -X POST -H 'Authorization: Bearer YOUR-ACCESS-TOKEN' -H 'Content-Type: application/json' -d '{ "item": { "name": "Coffee", "price": 2.99 } }' http://localhost:7000/items -
您将收到403错误,表示权限不足。
使用管理员用户测试
- 登录管理员账户。
- 使用相同的命令创建新项目,操作应成功。
总结
通过本教程,您学习了如何使用Auth0和NestJS实现基于角色的访问控制(RBAC)。这种方法不仅提高了API的安全性,还提供了灵活的权限管理机制。接下来,您可以尝试将此应用程序部署到云平台,或集成更多功能,如GraphQL或gRPC。
原文链接: https://auth0.com/blog/developing-a-secure-api-with-nestjs-adding-role-based-access-control/
最新文章
- 使用NestJS开发安全API:角色管理 – Auth0
- 使用REST Assured进行API自动化测试(全面指南)
- 使用 Go 1.22 和 http.ServeMux 构建 REST API | 作者: Shiju Varghese
- 掌握API端到端测试:全面指南
- Tesults博客:API自动化测试指南
- 介绍全新的Rust REST API客户端库
- DeepSeek R1 × 飞书多维表格赋能教育领域
- 使用 C++ 和 Win32 API 创建 GUI 窗口应用程序:从零构建 Windows 桌面界面
- 深入解析什么是API安全
- 一个平台对接所有API:企业级API集成解决方案
- 台湾可以用支付宝吗?:支付与收款指南
- 深入解读 API Gateway:设计原则、实践与最佳架构