如何在Nest.JS中使用多个秘密来实现多个JWT策略

问题描述 投票:0回答:5

我喜欢实施多个名为“passport-JWT”的策略,每个策略都有自己的

secret
。有什么办法可以实现吗? 据我从文档了解到,在模块初始化期间只能注册一个秘密:

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService, JwtModule],
})
jwt passport.js nestjs passport-jwt nestjs-jwt
5个回答
12
投票

为了允许注册同一服务的多个变体,您将需要使用自定义提供程序和包装器模块

JwtModule
。它可能看起来像这样:

@Module({
  imports: [JwtModule.register({
    secret: secret1,
    signOptions: { expiresIn: '60s' },
  })],
  providers: [{
    provide: 'JwtSecret1Service',
    useExisting: JwtService,
  }],
  exports: ['JwtSecret1Service'],
})
export class JwtSecret1Module {}

现在您可以使用

@Inject('JwtSecret1Service')
来使用此特定配置,只要
JwtSecret1Module
已添加到使用模块的
imports
即可。您可以根据需要使用任意多个
JwtService
变体来完成此操作,并且每个变体都将保留其自己的配置


3
投票

基本上,当您创建策略时,您可以为策略名称添加第二个参数。然后您可以在

AuthGuard
上指定您需要的 JWT 策略。

// auth/strategy/jwt-access.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable()
export class AccessTokenStrategy extends PassportStrategy(Strategy, 'jwt-access-token') {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'access-token-secret',
    });
  }
  async validate(payload: any) {
    // your validate implementation here
    return {};
  }
}

// auth/guard/jwt-access-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class AccessTokenAuthGuard extends AuthGuard('jwt-access-token') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}

您可以保持

auth.module.ts
不变,在您的服务中您可以使用
jwtService.sign
的选项参数,如下面的代码所示

@Injectable()
export class AuthService {
  ...
  login(user: User) {
    return {
      access_token: this.jwtService.sign({ /* object to sign */ }),
      refresh_token: this.jwtService.sign(
        { /* object to sign */ }
        { secret: 'refresh-token-secret', expiresIn: '14d' },
      ),
    };
  }
}

2
投票

几天前我也做了同样的事情。 我创建了刷新令牌和访问令牌。 这是应用程序模块:

imports: [..., JwtModule.register({})]

我就这样注册了JwtModule。 如果您想创建访问令牌: 访问令牌策略:

export class AccessStrategy extends PassportStrategy(Strategy, 'access') {
constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: JwtConstants.access_token_secret,
    });
  }

  validate(payload: any) {
    return payload;
  }
}

如果您想创建访问令牌:

accessToken(userId: number, username: string) {
const token = this.jwtService.signAsync(
  {
    sub: userId,
    username: username,
  },
  {
    secret: JwtConstants.access_token_secret,
    expiresIn: 60,
  },
);
if (token) {
  return token;
}
return null;
}

您可以对刷新令牌或其他令牌执行相同的操作


1
投票

我最近创建了一个包来管理它,扩展了 Passport-jwt 以允许将 Passport-jwt 配置数组传递给构造函数。当请求到达时,使用标准的 Passport-jwt 代码并行检查每个配置,以查看 JWT 是否应该获得授权。

这是软件包:https://www.npmjs.com/package/@mestrak/passport-multi-jwt

在 NestJS 中,您可以在

jwt.strategy.ts
中执行类似的操作(或者任何您的策略设置文件的名称。

import { ExtractJwt, Strategy } from '@mestrak/passport-multi-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super([{
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'a_secret_key',
    },
    {
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'another_secret_key',
    }]);
  }

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

0
投票

添加所需的防护,如 AuthGuard(['jwt', 'jwt_2']),然后像此导出类 JwtStrategy 扩展 PassportStrategy(Strategy, 'jwt') {}

导出类 JwtStrategy2 扩展 PassportStrategy(Strategy, 'jwt2') {}

© www.soinside.com 2019 - 2024. All rights reserved.