NestJS-如何在jwt服务上创建包装服务(来自jwt模块)

NestJS-如何在jwt服务上创建包装服务(来自jwt模块),jwt,nestjs,nestjs-jwt,Jwt,Nestjs,Nestjs Jwt,对不起,我的英语不好,我来自乌克兰:) 您能告诉我如何创建我自己的服务吗?它扩展了npm包中Jwt模块提供的Jwt服务?我想为捕获错误创建自己的JwtService,并隔离用于令牌创建和验证的重复逻辑。请帮帮我怎么做。代码样本附件 import { BadRequestException, Injectable } from '@nestjs/common'; import { JwtService as NestJwtService, JwtVerifyOptions } from '@nes

对不起,我的英语不好,我来自乌克兰:) 您能告诉我如何创建我自己的服务吗?它扩展了npm包中Jwt模块提供的Jwt服务?我想为捕获错误创建自己的JwtService,并隔离用于令牌创建和验证的重复逻辑。请帮帮我怎么做。代码样本附件

import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtVerifyOptions } from '@nestjs/jwt';

@Injectable()
export class OwnJwtService extends NestJwtService {
  constructor() {
    super({});
  }

  async verifyAsync<T>(token: string, options?: JwtVerifyOptions): Promise<T> {
    try {
      const res = await super.verifyAsync(token, options);
      console.log('res', res);
      return res;
    } catch (error) {
      // My own logic here ...
      throw new BadRequestException({
        error,
        message: 'Error with verify provided token',
      });
    }
  }
}
但这对我不起作用,我也有类似的错误:

错误:嵌套无法解析OwnJwtService(?)的依赖项。请确保索引[0]处的参数JwtService在AuthModule上下文中可用


首先,请注意JwtModule基本上是基于
jsonwebtoken
创建一个模块的,您的自定义错误不需要在其中处理

其次,当您使用registerAsync时,您需要像
ConfigService.get('JWT\u SECRET')
中那样使用ConfigService获取您的ENV变量

第三,你的问题效率低下。JwtModule已经完成了您需要的所有操作。你只需要实现它。同样,只需将其视为适用于Nest的
jsonwebtoken
包。就这样

在注册时,当您创建新令牌时,登录和刷新令牌(如果存在)将路由您签名。 在您的请求中间件中,您可以
验证

Nest的一个大问题是它的文档。它没有你需要的一切。验证路由的方法可能不止一种,但最简单的方法就是使用Express中间件,就像在典型的Express应用程序中一样

为此,您需要在AppModule中实现它,如下所示:

@Module(...)
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
    consumer.apply(cookieParser(), AuthMiddleware).forRoutes('/');
  }
}
在本例中,我还注册了模块
cookieParser()
,因为我在cookie中发送令牌。其他cookie模块也可以。NestModule和MiddlewareConsumer都来自@nestjs/common

AuthMiddleware是我使用此框架制作的中间件

export class AuthMiddleware implements NestMiddleware {
  constructor(
    private readonly configService: ConfigService,
    private readonly jwtService: JwtService
  ) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const { yourJwtToken } = req.cookies;
    const isValidToken = this.jwtService.verify(
      yourJwtToken,
      this.configService.get('JWT_SECRET'),
    );

    if (!isValidToken) throw new UnauthorizedException();

    // etc...

    next();
  }
}
最后,您可能会要求应用AuthGuard

如果您使用Passport,您只需按照文档进行应用即可。他们已经抛出错误,如果你。如果你想改变它,只需重写它的方法

您也可以手动执行此操作。只需使用控制台生成一个防护,在那里您可以检查身份验证
context.switchToHttp().getRequest()
,并在检查凭据后返回一个布尔值,如果需要,还可以使用构造函数检查权限

如果愿意,您还可以跳过上面的中间件配置,并在保护内部实现逻辑


同样,我并不认为更改JwtModule是最好的主意。

第一个解决方案是正确的。你在使用它时有什么错误吗?
@Module(...)
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
    consumer.apply(cookieParser(), AuthMiddleware).forRoutes('/');
  }
}
export class AuthMiddleware implements NestMiddleware {
  constructor(
    private readonly configService: ConfigService,
    private readonly jwtService: JwtService
  ) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const { yourJwtToken } = req.cookies;
    const isValidToken = this.jwtService.verify(
      yourJwtToken,
      this.configService.get('JWT_SECRET'),
    );

    if (!isValidToken) throw new UnauthorizedException();

    // etc...

    next();
  }
}