graphql - 在 Nestjs 中使用 graphql 进行授权
问题描述
我已经开始学习 Nestjs、express 和 graphql。我在尝试授权使用 jwt 令牌进行身份验证的用户访问时遇到问题。我按照Nestjs 网站上的身份验证教程进行操作。我能够获取当前用户,但是当我尝试实现基本角色基础访问控制时,我无法在 canActivate 方法中访问当前用户。我认为这是因为 Roles Guard 在 Graphql Guard 之前执行。
我将在这里发布代码
gql-auth.guard.ts
import { ExecutionContext } from "@nestjs/common";
import { GqlExecutionContext } from "@nestjs/graphql";
import { AuthGuard } from "@nestjs/passport";
export class GqlAuthGuard extends AuthGuard("jwt") {
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
console.log("gql simple context: ", context);
console.log("gqlContext: ", ctx.getContext());
return ctx.getContext().req;
}
}
角色.guard.ts
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { GqlExecutionContext } from "@nestjs/graphql";
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext) {
const roles = this.reflector.get<string[]>("roles", context.getHandler());
const ctx = GqlExecutionContext.create(context);
console.log("roles: ", roles);
console.log("context: ", context.switchToHttp().getRequest());
console.log("gqlContext: ", ctx.getContext().req);
return true;
}
}
jwt.strategy.ts
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";
import { jwtConstants } from "../constants";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
validate(payload: any) {
console.log("payload: ", payload);
return payload;
}
}
解析器
@UseGuards(GqlAuthGuard)
@Roles("ADMIN")
@UseGuards(RolesGuard)
@Query((returns) => [Specialty], { nullable: "itemsAndList", name: "specialties" })
async getSpecialties(@Args() params: FindManySpecialtyArgs, @Info() info: GraphQLResolveInfo) {
const select = new PrismaSelect(info).value;
params = { ...params, ...select };
return this.prismaService.specialty.findMany(params);
}
有没有人成功实施过这个?
解决方案
您应该在同一个@UseGuards()
装饰器中使用两个警卫。喜欢@UseGuards(GqlAuthGuard, RolesGuard)
。Nest 将按顺序运行这些程序而不会出现问题。
推荐阅读
- javascript - Javascript 示例中的提升
- python - 带有 Flask 的 Restful API 和带有 Raspberry Pi 的 MySQL 数据库
- c# - Unity 2d:对象在被销毁后在场景重新加载时重新实例化
- javascript - 无法访问状态对象(React useState hook)
- sql - 如何在同一查询中使用多个不同的计数与 Druid SQL 中的其他列?
- ios - 如何创建基于对象的渐变着色器,而不是纹理或面?
- python - 通过python检查网站是否有效
- next.js - 在搜索中按 Enter 时数据不会更新
- docker - rabbitmq-server - 与非 root 用户分离被阻塞
- python - 如何创建检查点并从检查点或保存的 GAN 模型中恢复权重?