是否可以使用NestJS在passport中实现多个本地策略



我有一个场景,需要使用Passport本地策略为应用程序中的管理员和普通用户实现身份验证机制。我为这里描述的普通用户实现了该策略。它运行得很好。

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

我的本地策略是这样的:

@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登录的情况下,我将使用不同的路由,比如(admin/login(,对于用户来说,它可能是(user/login(。

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

替代方案之一可以是每次检查每个登录负载的数据是否存在于两个表中。这种方法在我看来不太正确。

如果这提供了更多的见解,那么auth-guard就简单如下:

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

您可以基于passport-local制定第二个策略,但通过遵循文档的命名策略部分,为其指定一个类似admin的名称。类似的东西

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

现在,您可以通过使用@UseGuards(AuthGuard('admin'))来使用此策略,并通过向AuthGuard提供一系列策略名称来添加几个策略,例如:

@UseGuards(AuthGuard(['admin', 'user']))

如果其中一个策略通过,则将接受路由访问。

最新更新