我使用Passport和GraphQL,如果我做自己的自定义保护措施来获取用户的角色,那将是行不通的。我无法通过Guard中的请求访问用户,这是故意的吗?我认为这应该是请求的一部分(我对NestJS完全陌生),所以为什么我不能得到它?我想直接从用户对象获取用户的角色,并且只允许具有Admin的用户执行特定的路由,例如用户的完整列表。
这是我的GraphQL防护,控制台日志始终返回未定义
@Injectable()
export class GraphqlPassportAuthGuard extends AuthGuard('jwt') {
roles: string[];
constructor(roles?: string | string[]) {
super();
this.roles = Array.isArray(roles) ? roles : [roles];
}
canActivate(context: ExecutionContext): boolean {
const ctx = GqlExecutionContext.create(context);
const req = ctx.getContext().req;
console.log('graphql guard user', req && req.user)
return true;
}
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
const req = ctx.getContext().req;
console.log('graphql guard user', req && req.user)
return req;
}
}
我尝试将其与以下代码配合使用
export const CurrentUser = createParamDecorator(
(data, [root, args, ctx, info]) => {
return ctx.req.user;
},
);
@Resolver()
export class UsersResolver {
constructor() { }
@Query(() => UserDto)
@UseGuards(GraphqlPassportAuthGuard)
whoAmI(@CurrentUser() user: User) {
return user;
}
}
app.module.ts
@Module({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: 'schema.gql',
context: ({ req }) => ({ req }),
}),
// ...
});
我可以使用自定义装饰器从@CurrentUser()
获取用户,但无法在防护罩中获取用户对象。我正在尝试从请求中获取用户,但这是否可以在Guard中进行?我尝试了很多事情,我不知道该怎么办。
我还尝试使用不同的代码创建另一个Roles Guard,然后再次尝试从请求中获取用户,而无法从请求中获取用户。
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) { }
canActivate(context: ExecutionContext): boolean {
const handler = context.getHandler();
const http = context.switchToHttp();
const request = context.switchToHttp().getRequest();
const roles = this.reflector.get<string[]>('roles', context.getHandler());
console.log('rolesGuard', roles, request && request.user)
if (!roles || !request || !request.user) {
return true;
}
const user = request && request.user;
const hasRole = () =>
user.roles.some(role => !!roles.find(item => item === role));
return user && user.roles && hasRole();
}
}
答案 0 :(得分:1)
在您的GraphqlPassportAuthGuard.canActivate()
上,您应该致电super.canActivate(context)
,这是@ nestjs / passport AuthGuard
将用户放置在Request对象中的地方。
如果由于某种原因,您不希望在用户未通过身份验证时触发防护措施,则还必须覆盖AuthGuard.handleRequest(err, user, info, context)