自定义jwt策略NestJs的验证失败响应

时间:2020-02-03 15:32:15

标签: authentication jwt nestjs passport-jwt

我成功地使用nestJs实现了jwt策略进行身份验证。

下面是jwt策略的代码

import { ServerResponse } from './../helpers/serverResponse.helper';
import { Injectable, UnauthorizedException, HttpStatus } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { config as env } from 'dotenv';
import { Bugsnag } from '../helpers/bugsnag.helper';

env();

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor(
    private readonly logger: Bugsnag,
    ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET_KEY,
      passReqToCallback: true,
    });

  }

  async validate(payload, done: Function) {
    try {
      const validClaims = await this.authService.verifyTokenClaims(payload);

      if (!validClaims)
          return done(new UnauthorizedException('invalid token claims'), false);
      done(null, payload);
    } catch (err) {
      this.logger.notify(err);
      return ServerResponse.throwError({
        success: false,
        status: HttpStatus.INTERNAL_SERVER_ERROR,
        message: 'JwtStrategy class, validate function',
        errors: [err],
      });
    }
  }
}

我看到here仅在请求标头中提供了有效令牌时才会调用validate函数,我可以接受。但是,我想知道是否可以自定义在这种情况下发送的响应对象(提供的无效令牌)。

如果是,我该怎么做?

2 个答案:

答案 0 :(得分:1)

如果需要,您可以使用exception filter来捕获UnauthorizedException,并在那里修改响应。另一个选择是扩展AuthGuard('jwt')混合类,并为try/catchsuper.canActivate(context)周围添加一些逻辑,然后在错误中读取原因并抛出特定的{{1 }}和您的自定义消息

答案 1 :(得分:0)

您可以使用 AuthGuard('jwt')handleRequest 方法在 JWT 验证失败时抛出任何异常。

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  handleRequest(err: any, user: any, info: any, context: any, status: any) {
    if (info instanceof JsonWebTokenError) {
      throw new UnauthorizedException('Invalid Token!');
    }

    return super.handleRequest(err, user, info, context, status);
  }
}

JsonWebTokenError 来自 jsonwebtoken 库,由 Passport 内部使用。