使用 JWT 策略的 NestJs 身份验证 - 添加 "ignoreNotBefore" 的验证选项

NestJs authentication with JWT strategy - add validation option of "ignoreNotBefore"

我在 NestJs 中使用 AuthGuard 来验证请求 jwt 令牌。 因为我的服务只是验证令牌而不是创建令牌,它不能使用“nbf”验证以避免创建令牌的服务器时间晚于我的服务器的情况。

当使用纯 node.js 使用 jsonwebtoken 库时,很容易通过添加选项来关闭此验证:

jwt.verify(token, cert, {ignoreNotBefore: true})

这也有效。 但是,我如何使用 nest 来做到这一点?

这是我的守卫:

    @Injectable()
    export class JwtAuthGuard extends AuthGuard('jwt') {

     constructor(private reflector: Reflector,
              private authService: AuthService) {
       super();
     }

     async canActivate(context: ExecutionContext) {
       const isValid = await super.canActivate(context);
       return isValid;
     }

     handleRequest(err, user, info) {
       if (err || !user) {
         Logger.error(`Unauthorized: ${info && info.message}`);
         throw err || new UnauthorizedException();
      }
      return user;
    }
   }

在 JWT 策略中,我尝试在调用 PassportStrategy 的“super”时添加 ignoreNotBefore 选项,但这是行不通的:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService,
              private config: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      ignoreNotBefore: true,
      secretOrKey: fs.readFileSync(config.get('auth.secret')),
    });
  }

  validate(payload: any) {
     const isAuthorized = this.authConfig.roles.some((role) => payload.role?.includes(role));
     if(!isAuthorized) {
        Logger.error(`Unauthorized: Invalid role`);
        throw new UnauthorizedException();
    }
    return true;
  }
}

正确的做法是什么?

谢谢。

JwtAuthGuard


@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService,
              private config: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      jsonWebTokenOptions: {
        // this object maps to jsonwebtoken verifier options
        ignoreNotBefore: true,
        // ...
        // maybe ignoreExpiration too?
      },
      secretOrKey: fs.readFileSync(config.get('auth.secret')),
    });
  }

  validate(payload: any) {
     const isAuthorized = this.authConfig.roles.some((role) => payload.role?.includes(role));
     if(!isAuthorized) {
        Logger.error(`Unauthorized: Invalid role`);
        throw new UnauthorizedException();
    }
    return true;
  }
}</pre>

说明

将您的 ignoreNotBefore 移至 jsonWebTokenOptions,因为此对象映射到 jsonwebtoken 验证器选项。这是因为 Nest.js 包裹了 passport-jwt 并且 passport-jwt 包裹了 jsonwebtoken。所以根对象中的options主要是配置策略(passport),并没有配置jsonwebtoken(as much)。

了解更多

  1. http://www.passportjs.org/packages/passport-jwt/