如何在Nestjs中创建具有动态异步秘密的一次性Jwt?

时间:2020-05-01 10:32:56

标签: jwt passport.js nestjs

我的目标是

  1. 创建一次性令牌,使用户能够验证电子邮件
  2. 使用忘记的密码功能实现类似的操作

我无法在auth.module中对令牌进行签名,因为它是动态的,但我可以在auth.service中像这样进行签名:

private async getVerifyEmailToken(email:string,secret:string){
     // secret = user email +'_'+ user updated_on
     const payload:JwtPayload = {email};
     return jwt.sign(payload, secret, { expiresIn: '1h' });
};

当我尝试在JwTEmailStrategy中验证令牌时出现问题,因为我从数据库中异步检索了用户信息。

控制器:

@Get('/verify-email/')
    @UseGuards(AuthGuard('email-jwt'))
    async verifyEmail( 
        @GetMember() member:Member, 
        @Res() res: Response, @Next() next:NextFunction):Promise<void> {
            // do stuff
        }

    } 

在这里,我被困在JwtStrategy:

  import { PassportStrategy } from '@nestjs/passport';
  import { Strategy, ExtractJwt } from 'passport-jwt';  
  //other imports

  @Injectable()
    export class JwtEmailStrategy extends PassportStrategy(Strategy, 'email-jwt') {
        private logger = new Logger('JwtEmailStrategy');
        constructor(
            private readonly authService: AuthService,
        ) {
            super({
                jwtFromRequest: ExtractJwt.fromUrlQueryParameter('token'),
                ignoreExpiration: false,
                secretOrKeyProvider: (request, jwtToken, done) => {
                    const decodedToken:any  = jwt.decode(jwtToken);

                    if (!decodedToken) {
                        this.logger.error(`Failed token in JWT email validate`);
                        throw new UnauthorizedException({message: dbStrings.e_unauthorized});
                    }
                    // I'm calling the database and this is actually async, so what can I do?
                    // returns Promise { <pending> }
                    const result:any = this.authService.getMember(decodedToken.email);
                    done(null, result.email +'_'+ result.updated_on);
                },
              });
        }

        //ToDo validate

    }

也尝试用'await'调用它,但不允许:

await this.authService.getMember(decodedToken.email);

我正在使用node-postgres调用数据库,并且正在返回authService.getMember()的承诺。我找到了这个答案Using 'nestjs/jwt' signing with dynamic/user-related secret,但是它正在使用户信息同步,因此无法解决我的问题。

我是否可以在secretOrKeyProvider中调用该方法?还是有完全不同的方法来实现我想要做的事情?

0 个答案:

没有答案