【问题标题】:Nestjs How I can inject values in body request from session jwt req.userNestjs 如何从会话 jwt req.user 在正文请求中注入值
【发布时间】:2019-01-25 10:10:41
【问题描述】:

我创建了一个“自定义装饰器”,并使用它在主体请求中注入来自 jwt 会话用户的公司代码 (ZON_EMPRESA)。

// DECORATOR
import { createParamDecorator } from '@nestjs/common';
export const Zona = createParamDecorator((data, req) => {
    req.body.ZON_EMPRESA = req.user.USU_EMPRESA;
    return req.body;
});

验证在控制器中不起作用。如果我使用标准装饰器 @Body () 验证正确。 但我无法从 jwt 会话的 req.user 中注入值为 ZON_EMPRESA 的正文

// CONTROLLER
@Put('')
async update( @Zona() body: IZona ) {
    return await this.zonaonaService.update( body );
}

// VALIDATION
import { IsString, Length, IsInt, Min } from 'class-validator';
export class IZona {        
    readonly ZON_CODIGO?: number;

    @IsInt() 
    @Min(1)
    readonly ZON_EMPRESA: number;

    @IsString() 
    @Length(5, 50)
    readonly ZON_NOME: string;

    @IsInt() 
    @Min(1)
    readonly ZON_VENDEDOR: number;
}

我该如何解决这个问题。 谢谢

【问题讨论】:

    标签: typescript nestjs


    【解决方案1】:

    请求装饰器不适合您想要完成的任务,因为它们旨在从请求对象中检索信息,而不是用于改变它。您应该使用 interceptor 代替,因为它将在其余装饰器之前运行,允许您正确更新请求正文,以便 @BodyValidationPipe 自动拾取它(我假设您正在使用其他方式不会发生验证)。

    import { ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class CompanyCodeInterceptor implements NestInterceptor {
      intercept(
        context: ExecutionContext,
        call$: Observable<any>,
      ): Observable<any> {
        const req = context.switchToHttp().getRequest();
    
        req.body.ZON_EMPRESA = req.user.USU_EMPRESA;
    
        return call$;
      }
    }
    

    拦截器可以应用于方法、控制器或全局范围。例如,将其应用于控制器内的单个 HTTP 处理程序:

    @Post()
    @UseInterceptors(CompanyCodeInterceptor)
    exampleHandler(@Body() model: IZona) {
       // model is properly validated here, do whatever
       return model;
    }
    

    【讨论】:

    • 谢谢杰西卡特。您的解决方案是完美的
    • @ApicitoDiaz 没问题,很高兴我能提供帮助。也请随意对此答案进行投票,以便将来遇到此问题的其他人感到自信
    【解决方案2】:

    代替

    // DECORATOR
    import { createParamDecorator } from '@nestjs/common';
    export const Zona = createParamDecorator((data, req) => {
        req.body.ZON_EMPRESA = req.user.USU_EMPRESA;
        return req.body;
    });
    

    在控制器中使用User参数装饰器,并从用户那里获取此信息,并将其传递给服务。

    // DECORATOR
    import { createParamDecorator } from '@nestjs/common';
    export const User = createParamDecorator((data, req) => {
        return req.user;
    });
    
    // CONTROLLER
    @Put('')
    async update( @User() user: IUser ) {
        return await this.zonaonaService.update( user.USU_EMPRESA );
    }
    

    【讨论】:

    • 在我的真实代码中,我做同样的事情。但我的问题不在于这个,而是在我使用 @Zona() 装饰器时未验证的 ZON_VENDEDOR 字段,我在其中做更多为 ZON_EMPRESA 赋值的事情
    • @ApicitoDiaz 那么为什么不从实体上的类验证器调用验证呢?
    • 让它像@Body()一样工作看起来更清晰更简洁。
    • 我不明白为什么使用@Body () 它会进行验证并返回字段的错误而我的装饰器没有
    猜你喜欢
    • 2021-03-04
    • 2019-03-30
    • 1970-01-01
    • 2021-10-09
    • 2019-01-25
    • 2019-07-25
    • 1970-01-01
    • 2019-09-03
    • 2022-08-06
    相关资源
    最近更新 更多