是否可以使用 NestJS 实现护照中的多个本地策略

Is it possible to have multiple local strategies in passport implemented with NestJS

我有一个场景,我需要使用 Passport 本地策略在我的应用程序中为管理员和普通用户实施身份验证机制。我按照 here 所述为普通用户实施了该策略。它工作得很好。

但是,现在我需要为管理员登录实施相同的本地策略。我觉得如果两种类型的用户(管理员和普通用户)都在同一 entity/table 上会容易得多,因为单个验证函数足以处理这种情况,但我的应用程序设计具有单独的实体对于管理员和普通用户,因此是单独的服务。

我的本地策略是这样的:

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
    constructor(private userService: UserService) {
        super();
    }

    async validate(username: string, password: string): Promise<any> {
        const user = await this.userService.validateUser(username, password);
        if (!user) {
            throw new UnauthorizedException("Incorrect credentials!");
        }
        return user;
    }
}

当我阅读文档时,据说一个本地策略只能有一个验证函数(用作验证回调),如果是这种情况,我该如何区分这个单一验证函数中的逻辑对来自普通用户控制器和管理控制器的请求表现不同?因为在管理员登录的情况下,我将使用类似 (admin/login) 的不同路由,而对于用户,它可能类似于 (user/login).

最好的方法是什么?我是否需要为管理员创建单独的本地策略?如果是,任何提示将不胜感激。否则,我如何将逻辑合并到这个单一的验证函数中?

备选方案之一是每次都检查每个登录负载的数据是否存在于两个表中。这种方法对我来说不太合适。

如果这提供了更多的洞察力,那么 auth guard 很简单:

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') { 
}

您可以根据 passport-local 制定第二个策略,但按照文档的 named strategies 部分给它指定名称,例如 admin。像

@Injectable()
export class LocalAdminStrategy extends PassportStrategy(Strategy, 'admin') {
  validate(username: string, password: string) {
    return validateAdminInfo({ username, password });
  }
}

现在您可以使用此策略 @UseGuards(AuthGuard('admin'))