如何从控制器中的标头获取 JWT 令牌

Lil*_*taș 7 controller request http-headers nestjs

请帮我找到如何优化我的代码。我需要限制登录用户的数据。为此,我需要从 Request 的 JWT 令牌中获取 UUID。但我不喜欢我的方法,因为我有重复的代码:

const jwt = request.headers.authorization.replace('Bearer ', '');
const json = this.jwtService.decode(jwt, { json: true }) as { uuid: string };
Run Code Online (Sandbox Code Playgroud)

有谁知道我如何优化它?

这是我的控制器代码。

import { Controller, Get, Put, Body, Param, UseGuards, Req } from '@nestjs/common';
import { SettingService } from '../services';
import { AuthGuard } from '@nestjs/passport';
import { ResultInterface } from '../interfaces';
import { Request } from 'express';
import { JwtService } from '@nestjs/jwt';

@Controller('settings')
export class SettingController {
  /**
   * @param service
   * @param jwtService
   */
  constructor(private readonly service: SettingService,
              private readonly jwtService: JwtService) {
  }

  @UseGuards(AuthGuard('jwt'))
  @Get()
  async findAll(@Req() request: Request): Promise<ResultInterface> {
    const jwt = request.headers.authorization.replace('Bearer ', '');
    const json = this.jwtService.decode(jwt, { json: true }) as { uuid: string };
    const data = await this.service.findAll(json.uuid);
    return { rows: data };
  }

  @UseGuards(AuthGuard('jwt'))
  @Get(':id')
  async findOne(@Param('id') id: number, @Req() request: Request): Promise<ResultInterface> {
    const jwt = request.headers.authorization.replace('Bearer ', '');
    const json = this.jwtService.decode(jwt, { json: true }) as { uuid: string };
    const data = await this.service.findOneById(id, json.uuid);
    return { row: data };
  }

  @UseGuards(AuthGuard('jwt'))
  @Put()
  update(@Body() data: any, @Req() request: Request): Promise<any> {
    const jwt = request.headers.authorization.replace('Bearer ', '');
    const json = this.jwtService.decode(jwt, { json: true }) as { uuid: string };
    return this.service.update(data, json.uuid);
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 9

为了使您的代码更具可读性和透明性,您可以创建一个 @AuthUser() 装饰器并在您的所有控制器中重用它。当您使用 AuthGuard('jwt') 时,您已经在解码令牌,如果您再次使用 jwt.decode 函数,则会对令牌进行双重解码。

我在下面附上了返回我所有订单的用户装饰器和订单控制器函数的示例。

用户.decorator.ts

import { createParamDecorator } from '@nestjs/common';

export const AuthUser = createParamDecorator((data, req) => {
  return req.user;
});
Run Code Online (Sandbox Code Playgroud)

order.controller.ts

 @ApiOperation({ title: 'Get my orders' })
 @Get('/me')
 @UseGuards(AuthGuard('jwt'))
 async findMyOrders(@AuthUser() user: any): Promise<Order[]> {
   return this.orderService.findbyUserId(user._id);
 }
Run Code Online (Sandbox Code Playgroud)

  • 在我的例子中,用户对象并不直接位于“req”参数中。我必须按照[自定义装饰器 Nest 文档](https://docs.nestjs.com/custom-decorators#passing-data) 中所示访问它。调整答案将是“req.switchToHttp().getRequest().user”。`req` 是 `ExecutionContext` 类型,从 `@nestjs/common` 导入。 (4认同)
  • 创建装饰器的方法发生了变化,这里是关于它的文档 https://docs.nestjs.com/custom-decorators。 (3认同)