【问题标题】:NestJS custom decorator returns undefinedNestJS 自定义装饰器返回未定义
【发布时间】: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)。

感谢您的宝贵时间。

【问题讨论】:

    标签: typescript nestjs typeorm


    【解决方案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;
          }
          

          【讨论】:

            猜你喜欢
            • 2021-09-30
            • 2020-11-21
            • 2021-03-09
            • 2018-10-28
            • 2020-02-18
            • 2013-02-06
            • 2013-10-25
            • 2016-06-09
            • 2021-04-11
            相关资源
            最近更新 更多