NestJS中DELETE接口无法通过自定义GetUser()装饰器获取当前登录用户的问题排查
问题分析与解决方案
首先可以明确:这绝对不是HTTP DELETE方法本身导致的问题,GET接口能正常获取用户说明你的GetUser装饰器逻辑是对的,问题出在DELETE接口的认证配置或者请求本身。下面是几个最常见的原因和对应的解决办法:
1. 缺少认证守卫和Swagger认证标记
你的getMyItems接口加了@ApiBearerAuth()(用于Swagger文档标记需要Bearer令牌),但cancelRent接口没有,更关键的是——很可能你没有给这个DELETE接口添加认证守卫(比如JwtAuthGuard),而认证守卫正是负责解析请求头里的令牌、验证用户身份并把用户信息挂载到req.user上的核心逻辑。
解决办法:给cancelRent接口补上认证守卫和Swagger标记:
import { UseGuards } from '@nestjs/common'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; // 替换成你实际的守卫路径 @Delete('/:id/cancel') @ApiBearerAuth() // 用于Swagger识别需要令牌 @UseGuards(JwtAuthGuard) // 启用认证守卫 async cancelRent( @Param('id') id: number, @GetUser() user: User, ): Promise<void> { console.log(user); // 现在应该能正常输出用户信息了 return this.rentsService.cancelRent(id, user); }
2. 路由被标记为"公开",跳过了认证
如果你在项目中使用了自定义的@Public()装饰器(用于标记无需认证的接口),或者在全局认证配置中不小心把这个DELETE路由排除了,那么认证逻辑会被跳过,自然无法获取到req.user。
解决办法:
- 检查
cancelRent接口是否被添加了@Public()装饰器,如果有,移除它; - 检查全局守卫的配置(比如在
AppModule中注册APP_GUARD的地方),确认该路由没有被排除在认证范围外。
3. 请求未正确携带认证令牌
测试DELETE请求时,很容易忽略在请求头中携带Authorization: Bearer <你的JWT令牌>,如果没有这个令牌,认证守卫无法识别用户,req.user就会是undefined。
解决办法:
- 用Postman、Insomnia等工具测试时,确保请求头里包含正确的Authorization字段;
- 如果用curl测试,命令示例如下:
curl -X DELETE http://localhost:3000/your-rent-route/:id/cancel \ -H "Authorization: Bearer your-valid-jwt-token"
补充:完成租赁取消的权限校验
当你能正常获取到用户后,别忘了在rentsService中实现权限校验逻辑,确保只有租赁记录的所有者才能删除:
import { NotFoundException, ForbiddenException } from '@nestjs/common'; import { Rent } from './entities/rent.entity'; import { Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; @Injectable() export class RentsService { constructor( @InjectRepository(Rent) private readonly rentRepository: Repository<Rent>, ) {} async cancelRent(id: number, user: User): Promise<void> { // 1. 查询对应的租赁记录 const rentRecord = await this.rentRepository.findOne({ where: { id } }); if (!rentRecord) { throw new NotFoundException('租赁记录不存在'); } // 2. 校验当前用户是否是该记录的所有者 if (rentRecord.userId !== user.id) { throw new ForbiddenException('你只能取消自己的租赁记录'); } // 3. 执行删除操作 await this.rentRepository.remove(rentRecord); } }
内容的提问来源于stack exchange,提问作者Marko Marchisio
相关产品推荐
相关产品推荐

