如何用@nestjs/swagger和@UseGuards实现多API密钥一键授权?
问题描述
我当前使用@UseGuards验证请求头中的两个API密钥(some和thing),Guard实现代码如下:
@Injectable() export class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { // 同时检查请求头中的两个api密钥('some'和'thing') } }
同时在控制器中通过@ApiHeader在Swagger文档中展示这些密钥字段,控制器代码如下:
@ApiOperation({ summary: 'blah blah' }) @ApiHeader({ name: 'some'}, {name: 'thing'}) @UseGuards(AuthGuard) @Get('/hello') async adminableCollections() { // 业务逻辑 }
我希望替换@ApiHeader,改用@ApiSecurity或其他方式,通过Swagger的授权按钮一键完成所有接口的授权,无需在每个接口方法中手动输入密钥。此前尝试通过DocumentBuilder添加自定义安全配置,但未生效,配置代码如下:
const swaggerConfig = new DocumentBuilder() .setTitle('My API') .setDescription('Document for my api.') .setVersion('0.0.1') .addApiKey('some', { type: 'apiKey', in: 'header', name: 'some' }) .addApikey('thing', { type: 'apiKey', in: 'header', name: 'thing' }) .build();
请问是否有可行的解决方案?
可行解决方案
步骤1:定义复合API密钥安全方案
修改DocumentBuilder配置,将两个API密钥定义为独立安全方案,再通过全局安全要求组合起来,让所有接口默认启用双密钥验证:
const swaggerConfig = new DocumentBuilder() .setTitle('My API') .setDescription('Document for my api.') .setVersion('0.0.1') // 分别定义两个API密钥安全方案 .addSecurity('someApiKey', { type: 'apiKey', in: 'header', name: 'some' }) .addSecurity('thingApiKey', { type: 'apiKey', in: 'header', name: 'thing' }) // 全局要求同时使用两个密钥 .addSecurityRequirements(['someApiKey', 'thingApiKey']) .build();
步骤2:(可选)局部接口单独配置安全要求
如果不需要全局启用,可在单个控制器或接口方法上用@ApiSecurity指定双密钥验证:
@ApiOperation({ summary: 'blah blah' }) @ApiSecurity('someApiKey') @ApiSecurity('thingApiKey') @UseGuards(AuthGuard) @Get('/hello') async adminableCollections() { // 业务逻辑 }
步骤3:完善Guard的验证逻辑
确保Guard正确校验两个请求头密钥,示例实现:
@Injectable() export class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const someKey = request.headers['some']; const thingKey = request.headers['thing']; // 替换为你的实际密钥校验逻辑,比如从配置读取合法值 return someKey === 'VALID_SOME_KEY' && thingKey === 'VALID_THING_KEY'; } }
步骤4:验证Swagger效果
启动项目后打开Swagger文档,右上角的Authorize按钮点击后会弹出两个输入框,对应some和thing密钥。输入完成授权后,所有接口调用时会自动携带这两个请求头,无需逐个接口手动输入。
内容的提问来源于stack exchange,提问作者rin
相关产品推荐
相关产品推荐

