NestJS 自定义装饰器返回未定义
Posted
技术标签:
【中文标题】NestJS 自定义装饰器返回未定义【英文标题】:NestJS custom decorator returns undefined 【发布时间】:2020-06-30 09:20:24 【问题描述】:早上好,
我正在尝试创建自定义装饰器:
user.decorator.ts
import createParamDecorator, ExecutionContext from '@nestjs/common';
export const User = createParamDecorator(
(data: string, ctx: ExecutionContext) =>
const request = ctx.switchToHttp().getRequest();
const user = request.user;
return data ? user && user[data] : user;
,
);
user.entity.ts
import Entity, PrimaryGeneratedColumn, Column, BeforeInsert from "typeorm";
import * as bcrypt from 'bcryptjs';
import * as jwt from 'jsonwebtoken';
import UserRO from "./user.dto";
@Entity("user")
export class UserEntity
@PrimaryGeneratedColumn('uuid')
id: string;
@Column(
type: 'varchar',
length: 50,
unique: true,
)
username: string;
@Column('text')
password: string;
@Column('text')
role: string;
(...)
最后,user.controller.ts
(只有有用的部分):
(...)
@Post('login')
@UsePipes(new ValidationPipe())
login(@Body() data: UserDTO, @User('role') role: string)
console.log(`hello $role`);
return this.userService.login(data);
(...)
我的问题:console.log(...) 返回我hello undefined
,而预期的响应应该是hello admin
(因为管理员是数据库中用户的角色)
编辑:我也尝试在我的装饰器中 console.log(user)
并且它也未定义。
EDIT2:我的 HttpErrorFilter 还说:Cannot read property 'role' of undefined
我密切关注文档,但无法确定问题出在哪里 (https://docs.nestjs.com/custom-decorators)。
感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:我也对此感到困惑。我升级到 NestJS 7,并按照 migration guide 尝试更新我的用户装饰器。
我无法工作的部分是const request = ctx.switchToHttp().getRequest();
。出于某种原因,getRequest()
返回未定义。
对我有用的是:
import createParamDecorator, ExecutionContext from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) =>
return ctx.getArgByIndex(2).req.user;
);
execution context 文档建议不要使用getArgByIndex()
,所以我确定我做错了一些简单的事情。对其他答案和 cmets 会说什么感兴趣。
【讨论】:
【参考方案2】:我找到了解决办法。
在user.decorator.ts
:
将const user = request.user;
更改为const user = request.body;
根据nestjs 的文档,它应该是.user
,但是当我更深入地查看请求时,我注意到信息中没有“用户”而是“正文”。 (https://docs.nestjs.com/custom-decorators)
不知道是我之前搞砸了还是文档已经过时了。
问题解决了!
编辑:第二个解决方案:
我忘记在顶部使用@UseGuards(new AuthGuard())
,而request.user
是使用AuthGuard 创建的..
【讨论】:
【参考方案3】:我对这个空/未定义的请求很生气。因为文档中的信息 (custom-decorators) 对我不起作用。我正在使用graphql + typescript。那么神奇的解决方案是这样的:
export const CurrentUser = createParamDecorator(
(data: unknown, context: ExecutionContext) =>
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req.user;
,
);
【讨论】:
【参考方案4】:如果您对 HTTP(REST) 和 graphql 使用相同的装饰器
if (ctx.getType() == 'http')
return ctx.switchToHttp().getRequest().user;
else
const gqlContext = GqlExecutionContext.create(ctx);
return gqlContext.getContext().user;
【讨论】:
以上是关于NestJS 自定义装饰器返回未定义的主要内容,如果未能解决你的问题,请参考以下文章