问题
Good morning,
I'm trying to create a custom decorator:
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;
(...)
}
And finally, user.controller.ts
(only the useful part):
(...)
@Post('login')
@UsePipes(new ValidationPipe())
login(@Body() data: UserDTO, @User('role') role: string) {
console.log(`hello ${role}`);
return this.userService.login(data);
(...)
}
My problem: console.log(...) returns me hello undefined
, when the expected response should be hello admin
(as admin is the role of the user in the database)
EDIT: I also tried to console.log(user)
in my decorator and it is undefined too.
EDIT2: My HttpErrorFilter also says: Cannot read property 'role' of undefined
I followed closely the documentation and I can't figure out where the problem is (https://docs.nestjs.com/custom-decorators).
Thank you for your time.
回答1:
I found a solution.
In user.decorator.ts
:
Change const user = request.user;
with const user = request.body;
According to nestjs's doc, it should be .user
but when I looked deeper into the request, I noticed there were no 'user' but a 'body' with all in the informations. (https://docs.nestjs.com/custom-decorators)
Can't tell if I messed up earlier or if the doc is just outdated.
Problem solved whatsoever !
EDIT: 2nd solution:
I forgot to use @UseGuards(new AuthGuard())
on top, and the request.user
is created with the AuthGuard..
回答2:
I have also been confused about this. I upgraded to NestJS 7, and following the migration guide was trying to update my user decorator.
The part I could not get working is const request = ctx.switchToHttp().getRequest();
. For some reason getRequest()
was returning undefined.
What worked for me is:
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
return ctx.getArgByIndex(2).req.user;
}
);
The execution context docs advise against getArgByIndex()
, so I'm sure I'm doing something simple wrong. Interested in what the other answers and comments will say.
回答3:
I was getting mad with this empty/undefined request. Because that info in documentation (custom-decorators) was not working for me. I'm using graphql + typescript. Then the solution that did the magic was this:
export const CurrentUser = createParamDecorator(
(data: unknown, context: ExecutionContext) => {
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req.user;
},
);
来源:https://stackoverflow.com/questions/60753807/nestjs-custom-decorator-returns-undefined