open:graphql-authorization

GraphQL Authorization

비즈니스 로직 계층에 권한 부여 로직 위임1)

권한 부여는 주어진 사용자/세션/컨텍스트에 작업을 수행하거나 데이터를 볼 수 있는 권한이 있는지 여부를 설명하는 비즈니스 논리 유형입니다. 예를 들어:2)

“저자만 초안을 볼 수 있습니다”3)

이러한 종류의 동작을 적용하는 것은 비즈니스 로직 계층에서 발생해야 합니다. 다음과 같이 GraphQL 레이어에 권한 부여 로직을 배치하고 싶을 것입니다.4)

var postType = new GraphQLObjectType({
  name: ‘Post’,
  fields: {
    body: {
      type: GraphQLString,
      resolve: (post, args, context, { rootValue }) => {
        // return the post body only if the user is the post's author
        if (context.user && (context.user.id === post.authorId)) {
          return post.body;
        }
        return null;
      }
    }
  }
});

게시물의 authorId 필드가 현재 사용자의 ID와 같은지 여부를 확인하여 “작성자가 게시물을 소유함”을 정의합니다. 문제를 발견할 수 있습니까? 서비스의 각 진입점에 대해 이 코드를 복제해야 합니다. 그런 다음 권한 부여 논리가 다음과 같을 경우 완벽하게 동기화되지 않아 사용자는 사용하는 API에 따라 다른 데이터를 볼 수 있습니다. 좋아! 인증을 위한 단일 정보 소스를 사용함으로써 이를 방지할 수 있습니다.5)

GraphQL이나 프로토타이핑을 배울 때는 리졸버 내부에 권한 부여 로직을 정의하는 것이 좋습니다. 그러나 프로덕션 코드베이스의 경우 권한 부여 논리를 비즈니스 논리 계층에 위임합니다. 다음은 예입니다.6)

//Authorization logic lives inside postRepository
var postRepository = require('postRepository');
 
var postType = new GraphQLObjectType({
  name: ‘Post’,
  fields: {
    body: {
      type: GraphQLString,
      resolve: (post, args, context, { rootValue }) => {
        return postRepository.getBody(context.user, post);
      }
    }
  }
});

위의 예에서 비즈니스 로직 계층은 호출자가 사용자 개체를 제공해야 함을 알 수 있습니다. GraphQL.js를 사용하는 경우 사용자 개체는 해석기의 네 번째 인수에서 컨텍스트 인수 또는 rootValue에 채워져야 합니다.7)

불투명한 토큰이나 API 키 대신 완전히 수화된 사용자 개체를 비즈니스 논리 계층에 전달하는 것이 좋습니다. 이런 식으로 요청 처리 파이프라인의 여러 단계에서 인증 및 권한 부여의 고유한 문제를 처리할 수 있습니다.8)


1)
Delegate authorization logic to the business logic layer
2)
Authorization is a type of business logic that describes whether a given user/session/context has permission to perform an action or see a piece of data. For example:
3)
“Only authors can see their drafts”
4)
Enforcing this kind of behavior should happen in the business logic layer. It is tempting to place authorization logic in the GraphQL layer like so:
5)
Notice that we define “author owns a post“ by checking whether the post's authorId field equals the current user’s id. Can you spot the problem? We would need to duplicate this code for each entry point into the service. Then if the authorization logic is not kept perfectly in sync, users could see different data depending on which API they use. Yikes! We can avoid that by having a single source of truth for authorization.
6)
Defining authorization logic inside the resolver is fine when learning GraphQL or prototyping. However, for a production codebase, delegate authorization logic to the business logic layer. Here’s an example:
7)
In the example above, we see that the business logic layer requires the caller to provide a user object. If you are using GraphQL.js, the User object should be populated on the context argument or rootValue in the fourth argument of the resolver.
8)
We recommend passing a fully-hydrated User object instead of an opaque token or API key to your business logic layer. This way, we can handle the distinct concerns of authentication and authorization in different stages of the request processing pipeline.
  • open/graphql-authorization.txt
  • 마지막으로 수정됨: 2022/09/02 08:14
  • 저자 127.0.0.1