재우니의 블로그

 

ASP.NET CORE 환경에서 GraphQL 을 사용하며, 대신 인증을 통해 데이터를 가져오는 방법을 얻고자 찾아봤습니다. 아래 블로그는 이 부분에 대해 설명을 자세히 해 주고 있는데요.

 

조금 아쉬운 점은 ASP.NET CORE 5 버전이며, 또한 이에 종속되어 있는 컴포넌트들의 버전을 전부 최신으로 업데이트할 경우 알 수 없는 오류가 상당해서 아쉬운 점이 있습니다.

 

출처

https://www.codeproject.com/Articles/5295966/NET-5-Services-with-GraphQL-Data-Access-and-JWT

 

.NET 5 Services with GraphQL Data Access and JWT Authentication

Web services implementing GraphQL technology with repository access optimization, JSON Web Token (JWT) authentication and some other useful features.

www.codeproject.com

 

 

CLIENT 에서 LOGIN SERVICE 를 통해 ID, PWD 를 전송하여 맞으면 그에 맞는 JWT 를 반환해 주며, BEARER 에 JWT 값을 할당하고 요청할 GraphQL 구문을 통해 전송하여 json 형태로 반환받을 수 있습니다. 

 

좀 더 성능에 대해 고려해서 반영했는지, 매번 호출할때 마다 database 를 통해 가져오지 않고, cache 에 담아 최소한의 db connection 을 하는 부분이 인상적이었습니다.

 

참고로 메모리 캐시를 기반으로 한 데이터 수집 최적화는 성능을 향상시키지만 그 한계는 사용 가능한 작동 메모리(RAM)의 크기이며, 캐시 개체가 너무 커서 단일 프로세스 메모리에 수용할 수 없는 경우 Redis , Memcached 등과 같은 분산 캐시 솔루션을 사용할 수 있습니다.

 

 

 

데이터베이스를 2개 정도 만들어 사용하는데요.

 

Users 테이블을 보면, 아이디와 비밀번호 그리고 Role 을 1:1 형태로 저장되어 있습니다.

이는 인증을 통해 jwt 을 얻기 위한 인사테이블로 봐주시면 됩니다.

User 의 테이블에 Role 컬럼의 1,2,3 숫자값들은 아래와 같이 enum 으로 설명되어 있습니다.

namespace AuthRolesLib
{
    public enum UserAuthRole
    {
        Regular = 1,
        Admin = 2,
        SuperUser = 3
    }
}

 

아래는 PersonDb 는 각각 테이블에 관계가 설정되어 있으며, GraphQL 구문을 통해 관련되어 있는 부분을 가져오도록 구성되어 있습니다. 

 

 

소스를 전체적으로 받으면, 웹어플리이션 2개와 어플 1개, 테스터 1개 그리고 나머지는 라이브러리 입니다. 각각의 역할에 대해 아래 설명이 되어 있습니다. LoginService 가 인증부분을 담당하며, GraphQlService 은 GraphQl 구문을 분석하여 반환해 주는 웹서비스로 보시면 되겠습니다. ConsoleClient 은 콘솔 command 를 통해 GraphQl 을 활용하여 데이터를 얻는 가이드를 설명해 줍니다.

 

프로젝트 별 설명내용

 

위의 프로그램을 사용하기 위해 postman 툴을 활용할 예정이며, 가이드를 설명해 드리겠습니다.

 

인증을 위해 https://localhost:5011/login 를 post 로 호출합니다. Headers 에 content-type 을 applicaton/json 로 지정합니다.

 

body 에 row 를 json 으로 변환한 다음 username, password 를 통해 전송합니다. 그러면 body 에 string 형태의 jwt 문자열을 반환해 줍니다.

 

 

이제 GraphQl 구문을 통해 데이터를 얻고자 합니다. 인증 jwt 값을 auth 의 bearer token 에 값을 할당합니다.

 

 

body 에 GraphQL 로 변환한 다음, 아래 Query 입력란에 원하는 데이터를 얻기 위해 기술합니다. 

 

다음 Persons 쿼리는 모든 사람을 반환합니다.

query Persons {
  personQuery {
    persons {
      id
      givenName
      surname
      affiliations {
        organization {
          name
          parent {
            name
          }
        }
        role {
          name
        }
      }
      relations {
        p2 {
          givenName
          surname
        }
        kind
        notes
      }
    }
  }
}

 

아래 쿼리는 PersonById 고유한 매개변수 id 를 통해 한명의 사람을 반환합니다. 다음 예에서는 id가 1로 설정되어 있습니다.

 

query PersonById {
  personByIdQuery {
    personById(id: 1) {
	  id
	  givenName
      surname
      relations {
        p2 {
          id
	      givenName
          surname
        }
        kind
      }
      affiliations {
        organization {
          name
        }
        role {
          name
        }
      }
    }
  }
}

 

mutation PersonMutation 통해 사용자는 새로운 사람 정보를 저장하거나 기존 사람의 정보를 업데이트할 수 있습니다.

 

mutation PersonMutation {
  personMutation {
    createPersons(
      personsInput: [
        {
          givenName: "Vasya"
          surname: "Pupkin"
          born: 1990
          phone: "111-222-333"
          email: "vpupkin@ua.com"
          address: "21, Torn Street"
          affiliations: [{ since: 2000, organizationId: -4, roleId: -1 }]
          relations: [{ since: 2017, kind: "friend", notes: "*!", p2Id: -1 }]
        }
        {
          givenName: "Antony"
          surname: "Fields"
          born: 1995
          phone: "123-122-331"
          email: "afields@ua.com"
          address: "30, Torn Street"
          affiliations: [{ since: 2015, organizationId: -3, roleId: -1 }]
          relations: [
            { since: 2017, kind: "friend", notes: "*!", p2Id: -2 }
            { since: 2017, kind: "friend", notes: "*!", p2Id: 1 }
          ]
        }
      ]
    ) {
      status
      message
    }
  }
}

 

ServicesTest [통합 테스트] 는 프로젝트 (디렉토리 .\Tests ) 에 배치됩니다. 인메모리 서비스는 통합 테스트에 사용됩니다. 이 접근 방식은 통합 테스트를 개발하는 노력을 상당히 줄여줍니다. 테스트는 데이터베이스를 생성하고 초기에 채우기 때문에 즉시 실행될 수 있습니다.

 

 

이 작업에서는 트랜잭션 데이터 리포지토리와 함께 CRUD 작업을 위한 GraphQL 기술의 사용에 대해 설명하고 .NET 5 C#에서 개발된 적절한 서비스를 제시합니다. 또한 JWT 인증, OpenApi, 구성 가능한 로그 및 인메모리 서비스를 사용한 통합 테스트와 같은 유용한 기능을 구현합니다.