在NestJS中,如何构建一个警卫来验证用户的电子邮件是否已确认?

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

我正在使用 NestJS 10。我想创建一个保护端点的防护,不仅在用户登录时,而且在他们确认其电子邮件时也保护端点。我正在使用 NestJS/passport,并像这样创建 JWT 令牌

  async getTokens(userId: string, username: string) {
    const [accessToken, refreshToken] = await Promise.all([
      this.jwtService.signAsync(
        {
          sub: userId,
          username,
        },
        {
          secret: this.configService.get<string>('JWT_ACCESS_SECRET'),
          expiresIn: ACCESS_TOKEN_DURATION,
        },
      ),
      this.jwtService.signAsync(
        {
          sub: userId,
          username,
        },
        {
          secret: this.configService.get<string>('JWT_REFRESH_SECRET'),
          expiresIn: REFRESH_TOKEN_DURATION,
        },
      ),
    ]);

    return {
      accessToken,
      refreshToken,
    };
  }

我在我的身份验证模块中配置了此 AccessTokenStrategy ...

type JwtPayload = {
  sub: string;
  username: string;
};

@Injectable()
export class AccessTokenStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor() {
    console.log("access token strategy ...");
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_ACCESS_SECRET,
    });
  }

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

但我不知道如何保护我的电子邮件确认保护。我的用户实体有一个布尔值“isEmailConfirmed”属性,但如果我要构建这样的防护,我不太确定如何从有效负载中添加/提取该属性。

jwt nestjs passport.js guard
1个回答
0
投票

您没有提供数据库引擎,所以我假设它是 Prisma,尽管它在这里并不那么重要。

您可以按如下方式创建守卫:

import { Injectable, type CanActivate, type ExecutionContext } from '@nestjs/common';

import { DbUserService } from '@/modules/database/user.service';

interface GuardRequest {
    readonly userId: string;
}

@Injectable()
export class IsEmailConfirmedGuard implements CanActivate {
    constructor(private readonly dbUserService: DbUserService) {}

    public async canActivate(context: ExecutionContext): Promise<boolean> {
        const request = context.switchToHttp().getRequest<GuardRequest>();
        const user = request.userId;

        const isEmailConfirmed = await this.dbUserService.isEmailConfirmed(
            userId,
        );

        return isEmailConfirmed;
    }
}

当然,

isEmailConfirmed
函数应该根据
isEmailConfirmed
,在数据库中查询用户的
userId
属性值。

然后将防护应用到端点控制器:

import { Body, Controller, HttpCode, HttpStatus, Param, Patch, UseGuards } from '@nestjs/common';

import { IsEmailConfirmedGuard } from '@/guards/is-email-confirmed.guard';

import Routes from './example.routes';

@Controller(Routes.EXAMPLE_CONTROLLER)
export class ExampleController {
    @UseGuards(IsEmailConfirmedGuard)
    @Patch(Routes.EXAMPLE)
    @HttpCode(HttpStatus.OK)
    public async example(
    ): Promise<void> {
       return;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.