使用@UseGuards(JwtAuthGuard)时如何保留Swagger文档并获取req.user
解决方案
你可以直接在接口参数中同时注入@Req()请求对象和@Body()参数,两种装饰器互不影响,完全可以保留原有Swagger的文档生成能力。
步骤1:导入依赖
首先导入所需的请求相关装饰器和类型:
import { Controller, Post, Body, UseGuards, Req } from '@nestjs/common'; // 基于Express框架的话导入Request类型,用Fastify则对应导入FastifyRequest import { Request } from 'express';
如果需要解决TypeScript类型报错,可以全局扩展Request的user字段类型:
// 可放在当前控制器顶部或全局d.ts类型文件中 declare module 'express' { interface Request { // 替换为你实际的用户实体字段类型 user: { id: number; username: string; // 其他用户字段 } } }
步骤2:修改接口参数
直接在方法参数中追加@Req()注入的请求对象即可:
@UseGuards(JwtAuthGuard) @ApiBearerAuth('JWT') @Post() create( @Req() req: Request, @Body() createOrganizationDto: CreateOrganizationDto ) { // 直接获取JwtStrategy返回的用户对象 const currentUser = req.user; // 可根据业务需要将用户信息注入dto createOrganizationDto.createBy = currentUser.id; return this.organizationService.create(createOrganizationDto); }
这种写法完全保留了@Body()装饰器,Swagger可以正常识别CreateOrganizationDto的字段生成接口文档,不会产生任何影响。
优化方案:自定义用户参数装饰器
如果多个接口都需要获取当前登录用户,可以自定义专用装饰器简化写法:
// src/common/decorators/get-current-user.decorator.ts import { createParamDecorator, ExecutionContext } from '@nestjs/common'; export const GetCurrentUser = createParamDecorator( (field: string | undefined, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); const user = request.user; // 传入字段名则返回对应字段,否则返回完整用户对象 return field ? user?.[field] : user; } );
使用示例:
@UseGuards(JwtAuthGuard) @ApiBearerAuth('JWT') @Post() create( // 直接获取完整用户对象 @GetCurrentUser() currentUser: UserEntity, // 也可直接获取指定字段,比如@GetCurrentUser('id') userId: number @Body() createOrganizationDto: CreateOrganizationDto ) { createOrganizationDto.createBy = currentUser.id; return this.organizationService.create(createOrganizationDto); }
内容的提问来源于stack exchange,提问作者Emmanuel Amodu
相关产品推荐
相关产品推荐

