1

我正在尝试创建一个自定义装饰器以通过 Passport JWT 策略@CurrentUser获取集合。req.user令人困惑的是,在使用 NestJs 的内置记录器进行记录时以及在任何地方使用装饰器来获取用户并执行任何操作时,我都无法定义。req.user但是当我使用 javascript 'console.log' 方法记录 req.user 对象时,或者当我直接发送 req.user 作为响应时,预期的对象被正确记录/返回。

我究竟做错了什么?

当前用户.decorator.ts

import { createParamDecorator, ExecutionContext, Logger } from '@nestjs/common';
import { AuthPayload } from '../token/token.strategy';

const CurrentUser = createParamDecorator(
  async (_data: never, context: ExecutionContext): AuthPayload => {
    const req = context.switchToHttp().getRequest();

    Logger.verbose(req.user, 'CurrentUser'); // undefined
    console.log(req.user); // { id: ....., email: ... }

    return req.user;
  }
);

TokenStrategy.ts(JWT 策略实现):

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthConfig } from '../../../config';
import { User } from '../../user/user.entity';

export type AuthPayload = Pick<User, 'id' | 'avatarUrl' | 'displayName' | 'email'>;

@Injectable()
export class AuthTokenStrategy extends PassportStrategy(Strategy) {
  constructor(configService: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get<AuthConfig>('auth').jwt.secret,
    });
  }

  async validate(payload: AuthPayload) {
    return payload;
  }
}

更新:

解决。所以问题实际上是我的记录器(winston)和缺少等待的混合。我花了 2 天时间才完全弄清楚这一点。VSCode 调试器对找到这个有很大帮助。因此,如果您面临类似的问题,请确保您正在正确地等待您的承诺。如果您使用的是 winston 记录器,请抛弃它!即使你现在没有遇到问题,你很快就会挠头。

4

0 回答 0