인증 로직을 비즈니스 로직 레이어에 위임하세요
Presentation > Business Logic > Persistence > Database Layer
인증은 주어진 사용자/세션/컨텍스트가 작업을 수행하거나 데이터를 볼 수 있는 권한이 있는지 여부를 나타내는 비즈니스 로직입니다. 예를 들어,
이런 종류의 행동을 강제하는 것은 비즈니스 로직 레이어에서 일어나야합니다. GraphQL 레이어에 다음과 같이 인증 로직을 배치해야합니다. - Guard는 비지니스 로직 레이어에 속한다.
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에 따라 다른 데이터를 보게될 수도 있습니다. 단일 소스(single source of truth) 인증을 통해 이를 피할 수 있습니다.
GraphQL이나 프로토타이핑을 배울 때는 resolver 내부에 인증 로직을 정의하는 것이 좋습니다. 하지만, 프로덕션 코드의 경우에는 1) 비즈니스 로직 레이어에 인증 로직을 위임하세요. 아래는 그 예입니다.
1) Business Login Layer - provider, guard
// 인증 로직은 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);
}
}
}
});
위 예제에서, 비즈니스 로직 레이어는 호출자가 user 객체를 제공해야 한다는 것을 알 수 있습니다. GraphQL.js를 사용하는 경우, user 객체는 context 인수 또는 resolver 의 네 번째 인수인 rootValue 에 전달되어져야 합니다.
확실한 토큰이나 API key 대신 완전한 user 객체를 비즈니스 로직 레이어에 전달하는 것이 좋습니다. 이렇게하면 요청 처리 파이프라인의 여러 단계에서 인증 문제를 처리할 수 있습니다.
인증(Authentication)
사용자의 신원 확인 ex) 로그인, 회원가입
인가(Authorization)
신원이 확인된 사용자에게 리소스에 엑세스할 수 있는 권한 부여
인증
을 통해 AccessToken을 생성한다. 토큰에는 사용자 정보를 확인할 수 있는 정보가 포함된다.NestJS 에 적용
인증은 요청당 한 번만 수행하면 되므로 컨텍스트 수준 인증이 더 효율적이고 구현하기 쉽다.
그러나 리졸버마다 다른 수준의 인증이 필요한 경우와 같이 모든 사례에 적합하지 않을 수 있다. 리졸버 레벨 인증은 인증 및 권한 부여를 세밀하게 제어할 수 있지만 유지 관리가 복잡하고 어려울 수 있다.
NestJS 에 적용
리졸버가 프리젠테이션 레이어인지, 비지니스 로직 레이어인지는 코드 구현 방법에 따라 다르다. 레드플랫폼은 리졸버가 프리젠테이션 레이어로 정의되어 개발된 것이다.