Как я могу создать одноразовый JWT с динамическим c asyn c секретом в Nest js? - PullRequest
0 голосов
/ 01 мая 2020

Моя цель -

  1. Создать одноразовый токен, который позволяет пользователю проверять электронную почту
  2. Реализовать что-то похожее с функциональностью забытого пароля

I не могу подписать токен в auth.module, потому что он динамический c, но я могу сделать это в 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 (). Я нашел этот ответ Используя подпись 'nestjs / jwt' с динамическим / пользовательским секретом , но он получает информацию о пользователях синхронно, поэтому это не решает мою проблему.

Можно ли как-нибудь вызвать метод в secretOrKeyProvider? Или есть совершенно другой подход к достижению того, что я пытаюсь сделать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...