我有一个带有路线的控制器,我想用 Guards 来保护该路线。 我有这三个守则:IsAuthentifiedGuard、HasRoleGuard 和 IsSafeGuard,我希望这两个条件至少其中之一有效:
例如,如果用户经过身份验证并且具有足够的角色,则应该没问题,但如果没有,但调用是“安全的”,我也希望它没问题。
我的 OrGuard:
@Injectable()
export class OrGuard implements CanActivate {
constructor(private readonly orGuards: CanActivate[][]) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const orGuardsPromises = await Promise.all(
this.orGuards.map(async andGuards => {
const andGuardPromises = await Promise.all(
andGuards.map(async guard => {
return guard.canActivate(context)
}),
)
return andGuardPromises.every(canActivate => canActivate === true)
}),
)
return orGuardsPromises.some(canActivate => canActivate === true)
}
}
还有我的控制器:
@Controller('my_route')
export class MyController {
@Post('/')
@UseGuards(new OrGuard([[new IsAuthentifiedGuard(), new HasRoleGuard()], [new IsSafeGuard()]]))
async myRoute() {}
}
但是我对需要依赖的守卫有疑问。 例如,如果 HasRoleGuard 在构造函数中需要 ConfigService,则这是行不通的。
另一种方法是使用 my 或guard,如下所示:
@UseGuards(OrGuard)
@SetMetadata('orGuards', [[IsAuthentifiedGuard, HasRoleGuard], [IsSafeGuard]])
但是在我的守卫中,我没有成功地从类名中实例化这些守卫以及它们所需的所有依赖项。
你有什么建议?
@nest-lab/or-guard
实现。您需要将您的守卫注册为提供程序(只需将它们添加到提供程序数组即可),并且您需要为 AndGuard
创建一个自定义提供程序,以便稍后可以由 OrGuard
引用它。像这样的事情应该对你有用:
@Module({
providers: [
IsAuthentifiedGuard,
HasRoleGuard,
IsSafeGuard,
{
provide: 'AndGuard',
useClass: AndGuard([IsAuthenticatedGuard, HasRoleGuard]),
},
...
]
})
然后你可以使用
@UseGuards(OrGuard(['AndGuard', IsSafeGuard]))
,它应该可以正常工作。如果您愿意,您可以查看测试以获得有关其工作原理的更多灵感