GRANDstack을 사용하여 GraphQL 액세스 제어 용이성

만약 당신이... 에 관심이 있다면, 이 문장은 아마도 당신에게 적합할 것입니다.


빠르고 유연한 개발 경험:
  • 멀티 임차 어플리케이션
  • 사용자가 선택할 수 있는 어플리케이션:

  • 그들은 어떤 데이터를 공유하고 싶은지, 그리고

  • 세계보건기구와 공유
  • 공동 작업 어플리케이션
  • GRANDstack(즉 GraphQL, React, Apollo, Neo4j 데이터베이스)은 초기 응용 프로그램 개발의 기술 비용을 낮추었지만 상술한 액세스 제어 기능을 스스로 실현하는 것은 매우 복잡하거나 어려울 수 있다.이 공백을 메울 수 있는 패키지를 여러분과 공유해서 GRANDstack이 다음 MVP를 받을 수 있는 최선의 선택 중 하나가 되도록 하겠습니다.

    아주 오래 전에 먼 성계에서...


    과장하면 재미있지만 엄숙하다.얼마 전에 GRANDstack(즉 GraphQL,React,Apollo,Neo4j 데이터베이스)과 그 플러그인 관계 필터가 액세스 제어에 어떻게 응용되는지 연구하는 글을 썼습니다.마치 아주 오래된 것 같다.2020이라는 일이 일어났다. 대략적인 개념 검증 코드에서 내가 공유할 수 있는 것이 되는 데 시간이 걸렸다.
    그날이 이미 왔다.

    소개:neo4jdeepauth v0.2.0 버전

    neo4j-graphql-js GraphQL 노드(즉 GRANDstack 응용 프로그램)에서 명령에 기반한 세분화 접근 제어 지원.내가 공유한 초기 아이디어/코드에 비해 주의해야 할 개선사항은 다음과 같다.
  • 베이스라인filter 기능을 복원합니다.
  • @deepAuth에 대한 지원을 추가하여 인터페이스와 그 모든 대상 유형에 적용합니다.
  • neo4j deepauth 패키지 사용하기


    1. NPM 또는 사선으로 포장 설치

    yarn add neo4j-deepauth 또는 npm install neo4j-deepauthNPM 페이지로 연결: https://www.npmjs.com/package/neo4j-deepauth

    2. SDL에 @deepAuth 명령의 모드 정의를 추가합니다.


    유형 정의에는 다음과 같은 내용이 포함되어야 합니다.
    const typeDefs = `
      # Other TypeDefs you defined before
    
      directive @deepAuth(
        path: String
        variables: [String]
      ) on OBJECT | INTERFACE
    `
    
    현재 구현된 동작@deepAuth은 대상이나 인터페이스 유형에만 적용됩니다.neo4j-graphql-js 새 객체 유형 정의를 생성하는 방식으로 "관계 유형"을 열 복구하고 있습니다. 제한된 필드를 자신의 객체로 이동하고 주 유형과 일대일 관계를 맺어 필드 수준의 액세스 제어를 실현할 수 있습니다 (상당히 우아하지 않지만 간단함).

    3. 사용자 정의 유형에 명령을 추가합니다.


    이전에 정의된 유형 정의를 수정합니다. 방법은 @deepAuth를 적용할 모든 대상에 포함됩니다 User.다음과 같이 보일 수 있습니다.
    const typeDefs = `
    
    type User @deepAuth(
      path: """{ OR: [{userId: "$user_id"},
                    {friends_some: {userId: "$user_id"}}] }""",
      variables: ["$user_id"]
    ){
      userId: ID!
      firstName: String
      lastName: String
      email: String!
      friends: [User] @relation(name: "FRIENDS_WITH", direction: "OUT")
      taskList: [Task] @relation(name: "TO_DO", direction: "OUT")
      visibleTasks: [Task] @relation(name: "CAN_READ", direction: "IN")
    }
    
    type Task @deepAuth(
      path: """{ visibleTo_some: {userId: "$user_id"} }"""
      variables: ["$user_id"]
    ) {
      taskId: ID!
      name: String!
      details: String
      location: Point
      complete: Boolean!
      assignedTo: User @relation(name: "TO_DO", direction: "IN")
      visibleTo: [User] @relation(name: "CAN_READ", direction: "OUT")
    }
    
    # ...Directive definition from above
    `
    
    여기서 만약: a) 고객은 User이다.또는 b) 고객은 Tasks의 친구입니다.고객의 UserCAN_READ 관계가 있을 때만 Task 에 대한 접근을 제한합니다.이것은 유일하거나 가장 좋은 권한 수여 구조가 아니라 간단한 예일 뿐이다.path 매개변수는 ACL 구조의 존재성을 정의하는 필터 매개변수 입력 유형에 강하게 대응합니다.path 매개 변수 값을 올바른 필터 입력 유형으로 강제하려고 할 때, 이 유형에 맞지 않는 applyDeepAuth 매개 변수를 선언하면 오류가 발생할 수 있습니다.

    4. 해상도 및 요청 컨텍스트 수정

    @deepAuth 보다 광범위한 기능으로 neo4j-graphql-js 에 통합되지 않으면 자동으로 생성된 해상도에 의존할 수 없습니다.우리는 반드시 스스로 그것들을 수정해야 한다.
    GRANDstack docs에 따르면 "매 해상도에서neo4j-graphql()를 사용하여 해상도graphql 조회에 필요한 암호를 생성하여 조회 매개 변수, 상하문과resolveInfo 대상을 전달합니다."이것은 일반적으로 다음과 같이 보입니다.
    import { neo4jgraphql } from "neo4j-graphql-js";
    
    const resolvers = {
      // entry point to GraphQL service
      Query: {
        User(object, params, ctx, resolveInfo) {
          return neo4jgraphql(object, params, ctx, resolveInfo);
        },
        Task(object, params, ctx, resolveInfo) {
          return neo4jgraphql(object, params, ctx, resolveInfo);
        },
      }
    };
    
    위에서 말한 바와 같이, 우리는 이 해상도를 수정하여, 변환된 조회 세션으로 resolveInfo.operationresolveInfo.fragments 를 교체해야 한다.또한 최고급 필터는 neo4jgraphql() 파라미터에서 얻고, 후속 필터는 neo4jgraphql() 파라미터에서 얻는다는 것을 주의해야 한다.이것은 다음과 같이 보일 수 있습니다.
    import { neo4jgraphql } from "neo4j-graphql-js";
    import { applyDeepAuth } from "neo4j-deepauth";
    
    const resolvers = {
      // entry point to GraphQL service
      Query: {
        User(object, params, ctx, resolveInfo) {
          const { authParams, authResolveInfo } = applyDeepAuth(params, ctx, resolveInfo);
          return neo4jgraphql(object, authParams, ctx, authResolveInfo);
        },
        Task(object, params, ctx, resolveInfo) {
          const { authParams, authResolveInfo } = applyDeepAuth(params, ctx, resolveInfo);
          return neo4jgraphql(object, authParams, ctx, authResolveInfo);
        },
      }
    };
    
    params 명령에서 resolveInfo 을 사용하는 경우 요청 컨텍스트에서 variables 매개변수에 나타나는 키를 사용하여 정의해야 합니다.다음은 @deepAuth 상하문에서 variables 값을 추가하는 방법을 설명하는 예입니다. (주의: Apollo Server 문제는 v0.2.1 버전에서 진단되고 해결되었지만, express graphql에 지원을 제공할 수 있습니다.)
    const app = express();
    app.use('/', graphqlHTTP((request) => ({
      schema,
      context: {
        driver,
        deepAuthParams: {
          $user_id: request.user.id
        }
      },
      ...
    })));
    

    5. 사용자 정의 돌연변이 업데이트


    자동 생성된 돌연변이는 현재 deepAuthParams 에 제공된 권한 수여 경로를 존중하거나 강제하지 않습니다.그 밖에 express-graphql/@deepAuth 변이된 같은 업무에서 다른 권한 수여 노드/관계를 만들거나 삭제하는 것은 일반적으로 유익하거나 필요한 것이다.
    이러한 이유로 거의 모든 응용 프로그램Create이나 Deleteed 형식과 관계가 있는 형식을 위한 사용자 정의 돌연변이 해상도를 만들어야 합니다.

    예제

    @deepAuth 사용 예: github.com/imkleats/neo4j-deepauth-example

    엠클레츠 / neo4j deepauth 예


    neo4jgraphqljs와neo4jdeepauth가 있는 ApolloServer 예시


    문제와 공헌


    초기 버전 번호로 발표되었을 때, 나는 여전히 모든 변두리 사례를 식별하고 테스트 세트를 계속 충실하게 하려고 노력하고 있다.만약 버그나 미래의 기능 발표에 대해 생각이 있다면, Github 저장소에서 문제를 열어 보십시오.

    엠클레츠 / neo4j graphql deepauth


    neo4jgraphql jsgraphql 단점에서 지령을 기반으로 하는 세립도 접근 제어 지원


    감사합니다.네가 그것이 유용하다고 생각하기를 바란다. 나는 너의 편지를 받기를 기대한다.

    좋은 웹페이지 즐겨찾기