如何优化您的API端点:引入NestJS自定义...
优化您的 API 端点:引入 NestJS 自定义装饰器和 Guard
在本文中,我们将探讨如何通过创建自定义装饰器和 Guard 来优化 API 端点的安全性。具体来说,我们将使用 NestJS 框架实现一个基于模块权限的访问控制机制。
创建自定义装饰器
首先,我们需要创建一个自定义装饰器,用于将用户信息注入到请求中,并关联特定的模块权限。
使用 CLI 创建装饰器
通过 NestJS CLI,可以轻松生成装饰器文件。使用 --flat 选项可以避免生成额外的文件夹:
nest g decorator [your-architecture]/user-modules --flat
装饰器代码实现
以下是装饰器的代码实现,它使用了 SetMetadata 方法或 Reflector.createDecorator 方法来向控制器添加元数据,从而指定端点是否需要保护。
import { SetMetadata } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
// 定义可用的模块类型export type UserModule = 'management' | 'subscriptions' | 'roles';// 创建装饰器
export const UserModules = (modules: UserModule | UserModule[]) => SetMetadata('user-modules', modules);// 另一种实现方式,功能相同
export const UserModules = (modules: UserModule | UserModule[]) =>
Reflector.createDecorator('user-modules', modules);
通过以上代码,我们可以为控制器或端点指定需要的模块权限。
创建自定义 Guard
在创建了装饰器之后,我们需要实现一个 Guard,用于验证用户是否具有访问特定模块的权限。
使用 CLI 创建 Guard
同样可以通过 CLI 快速生成 Guard 文件,并使用 --no-spec 选项跳过测试文件(尽管建议为此类逻辑编写测试):
nest generate guard [your-architecture]/user-modules --no-spec --flat
Guard 代码实现
以下是 Guard 的核心代码,它会检索通过装饰器注入的模块权限,并验证当前用户是否具有访问权限:
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class UserModulesGuard implements CanActivate {
constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean {
// 获取模块元数据
const modules = this.reflector.get('user-modules', context.getHandler()); // 如果没有模块元数据,默认允许访问
if (!modules) {
return true;
} const request = context.switchToHttp().getRequest(); const userModules = request.user?.modules || []; // 验证用户是否具有访问权限
return modules.some((module) => userModules.includes(module));
}
}
通过以上代码,Guard 会根据用户的模块权限动态决定是否允许访问。
注册 Guard
创建完成后,需要将 Guard 注册到相关模块中。可以在控制器级别、方法级别或全局应用 Guard。
在控制器中应用 Guard
在控制器顶部添加 @UseGuards(UserModulesGuard):
import { Controller, UseGuards } from '@nestjs/common';
import { UserModulesGuard } from '[your-architecture]/user-modules.guard';
@UseGuards(UserModulesGuard)
@Controller('example')
export class ExampleController {
// 控制器逻辑
}
全局应用 Guard
如果需要全局应用 Guard,可以在根模块中配置:
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { UserModulesGuard } from '[your-architecture]/user-modules.guard';
@Module({
providers: [
{
provide: APP_GUARD,
useClass: UserModulesGuard,
},
],
})
export class AppModule {}
使用装饰器定义模块权限
现在,我们可以使用自定义装饰器为特定端点定义访问权限。例如:
import { UserModules } from '[your-architecture]/user-modules.decorator';
@UserModules('subscriptions')
public getSubscriptionsList() {
// 获取订阅列表的逻辑
}
通过上述代码,只有具有 subscriptions 模块权限的用户才能访问该端点。
总结
通过创建自定义装饰器和 Guard,我们可以轻松实现基于模块权限的访问控制。这种方法不仅提高了 API 的安全性,还能灵活地满足不同场景的需求。您可以根据具体需求调整代码逻辑,以适配不同的业务场景。
希望本文对您有所帮助!
原文链接: https://medium.com/@compte_94466/how-to-improve-your-api-endpoints-introducing-nestjs-custom-decorators-guards-5ddfb5ddffae
最新文章
- 创建 Python API
- LangGraph 教程:初学者综合指南
- 构建自定义云存储:NAS厂商 REST API 使用指南(Synology/QNAP)
- Pix支付方式是什么?如何在巴西和荷兰使用?
- Undetectable检查AI API的使用指南
- API优先设计三原则
- Password Manager(密码管理)产品背后的API机制:OAuth、加密接口、浏览器扩展集成
- AI短剧工业革命:API如何重塑内容生产全链路
- .NET Core 3.1 WebAPI+Vue+Element UI实现文件上传
- Python与Ollama的开发案例
- 知识图谱API解析
- 如何在Excel VBA中调用REST API