使用graphql在Nestjs中进行授权

使用graphql在Nestjs中进行授权,graphql,nestjs,nestjs-passport,nestjs-jwt,Graphql,Nestjs,Nestjs Passport,Nestjs Jwt,我已经开始学习Nestjs、express和graphql。 我在尝试授权使用jwt令牌验证的用户访问时遇到问题。 我按照教程的要求在服务器上进行身份验证。 我可以获取当前用户,但是当我尝试实现时,我无法在canActivate方法中访问当前用户。 我认为这是因为角色保护是在Graphql保护之前执行的 我会把密码贴在这里 gql-auth.guard.ts import { ExecutionContext } from "@nestjs/common"; import {

我已经开始学习Nestjs、express和graphql。 我在尝试授权使用jwt令牌验证的用户访问时遇到问题。 我按照教程的要求在服务器上进行身份验证。 我可以获取当前用户,但是当我尝试实现时,我无法在canActivate方法中访问当前用户。 我认为这是因为角色保护是在Graphql保护之前执行的

我会把密码贴在这里

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;
    }
}
分解器

@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()
装饰器中使用这两个防护。像
@usegards(GqlAuthGuard,RolesGuard)
。Nest将按顺序运行这些程序,不会出现问题。

您应该在同一个
@UseGuards()
装饰程序中使用这两个保护程序。像
@usegards(GqlAuthGuard,RolesGuard)
。Nest将按顺序运行这些程序,而不会出现问题

export const Authorize = (roles?: string | string[]) =>
  applyDecorators(
    SetMetadata('roles', [roles].flat()),
    UseGuards(GqlAuthGuard, RolesGuard),
  );
export const Authorize = (roles?: string | string[]) =>
  applyDecorators(
    SetMetadata('roles', [roles].flat()),
    UseGuards(GqlAuthGuard, RolesGuard),
  );
@Authorize("ADMIN")
@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);
}