You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS自定义装饰器返回undefined问题求助

问题分析与解决方案

你遇到的核心问题是在login接口中使用@User装饰器的时机不对,原因很简单:

login接口是用户的认证入口——用户还没完成登录流程,请求对象request上根本还没有user属性。@User装饰器的作用是从已经经过认证的请求中提取用户信息,而这依赖于你先通过认证守卫(比如JWT守卫)把用户信息挂载到request.user上。

为什么会出现undefined?

在login接口里,你还没有执行任何认证逻辑,request.user自然是undefined,所以装饰器返回的role也是undefined,后续的Cannot read property 'role' of undefined错误也由此而来。

正确的做法

1. 调整login接口的逻辑

login接口的作用是验证用户账号密码,返回token和用户信息,你应该直接从service返回的用户对象中获取role,而不是用@User装饰器:

@Post('login')
@UsePipes(new ValidationPipe())
async login(@Body() data: UserDTO) {
  const userRO = await this.userService.login(data);
  // 假设UserRO里包含role字段,如果是返回UserEntity则直接取user.role
  console.log(`hello ${userRO.role}`); 
  return userRO;
}

2. 在需要认证的接口中正确使用@User装饰器

如果你要在其他接口(比如用户个人信息接口)中使用@User装饰器,必须先确保该接口已经通过认证守卫的校验,守卫会把用户信息挂载到request.user上。举个例子:

首先你需要有一个JWT认证守卫(假设已经配置好JWT模块):

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

然后在需要认证的接口上使用这个守卫:

@Get('profile')
@UseGuards(JwtAuthGuard) // 先通过认证守卫,此时request.user已被挂载
getProfile(@User('role') role: string) {
  console.log(`hello ${role}`); // 这里就能正确输出hello admin了
  return { role };
}

补充说明

你的@User装饰器本身是没问题的,它的逻辑是正确的——问题出在使用它的场景不对。只有当请求已经经过认证流程,request.user被正确挂载后,这个装饰器才能发挥作用。

内容的提问来源于stack exchange,提问作者MA-Moustache

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:42:37