最终效果
通过装饰器直接取到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> {// 验证端点是否存在装饰器 SkipAuthconst 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}