自学内容网 自学内容网

nest通过装饰器获取jwt有效负载数据

最终效果

通过装饰器直接取到jwt中保存的数据

  @Get()
  findAll(@JwtPayload() jwtPayload, @JwtPayload('userId') userId) {
    console.log('>>>', jwtPayload);
    console.log('>>>', userId);
  }

原理说明(可以略过)

首先,看一下身份验证守卫代码

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { Request } from 'express';
import { IS_SKIP_AUTH } from './auto.decorator';
import { Reflector } from '@nestjs/core';

/**
 * 身份验证守卫
 * 验证接口中的jwt是否有效
 */

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private jwtService: JwtService,
    private reflector: Reflector,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    // 验证端点是否存在装饰器 SkipAuth
    const isSkipAuth = this.reflector.getAllAndOverride<boolean>(IS_SKIP_AUTH, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isSkipAuth) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });

      // 将有效负载挂载至request对象上
      request['jwtPayload'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

第46行,将解析完成后的payload挂载到request对象上 (我的代码是根据官网步骤来的,逻辑有差异的话自行修改)

那么,我们只需要取到request上的payload对象就行了

通过自定义装饰器实现

实现

export const JwtPayload = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const payload = request.jwtPayload;

    return data ? payload?.[data] : payload;
  },
);

验证 (controller控制器上)

  @Get()
  findAll(@JwtPayload() jwtPayload, @JwtPayload('userId') userId) {
    console.log('>>>', jwtPayload);// 打印数据对象
    console.log('>>>', userId);  // 打印对象中的userId
  }

原文地址:https://blog.csdn.net/qq_33982898/article/details/140356027

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!