[swift] 아폴로 서버를 사용한 인증 및 권한 관리

소개

아폴로 서버는 GraphQL을 사용하여 클라이언트와 서버 사이의 효율적인 데이터 통신을 제공하는 강력한 도구입니다. 이 문서에서는 아폴로 서버를 사용하여 인증 및 권한 관리를 구현하는 방법에 대해 알아보겠습니다.

1. 인증(Authentication)

클라이언트의 요청을 처리하기 전에 먼저 요청을 보낸 사용자의 인증 여부를 확인해야 합니다. 아폴로 서버는 context라는 매개변수를 통해 인증 정보를 전달받을 수 있습니다. 일반적으로 context에는 사용자의 인증 토큰이 포함되어 있습니다.

아래는 Swift에서의 예시 코드입니다.

public func makeApolloServer() -> ApolloServer {
    let server = ApolloServer(schema: schema)
    server.contextParser = { request in
        let authToken = request.http.headers["Authorization"].first?.replacingOccurrences(of: "Bearer ", with: "")
        return MyContext(authToken: authToken)
    }
    return server
}

인증 토큰을 검증하는 로직은 contextParser 클로저 내부에 작성합니다. 이 예시에서는 HTTP 요청의 Authorization 헤더에서 토큰을 추출하고, MyContext 객체에 저장하여 context로 전달합니다.

2. 권한 관리(Authorization)

인증에 성공한 사용자의 요청을 처리하기 전에는 해당 사용자가 해당 요청을 수행할 권한이 있는지 확인해야 합니다. 아폴로 서버는 context에 저장된 사용자 정보를 이용하여 권한을 검증할 수 있습니다.

아래는 Swift에서의 예시 코드입니다.

struct HasPermissionDirective: ApolloDirective {
    func visitObject(_ type: GraphQLNamedType, context: inout DirectiveVisitorContext) throws {
        // 사용자의 권한 검증 로직 구현
        let user = try context.getObject(User.self)
        let hasPermission = // 권한 검증 로직
        if !hasPermission {
            throw MyGraphQLError("Permission denied")
        }
    }
}

enum MySchemaBuilder {
    static func makeExecutableSchema() throws -> GraphQLSchema {
        let schema = try GraphQLSchema.build(...)

        try schema.apply(directive: HasPermissionDirective())
        
        return schema
    }
}

위 코드는 HasPermissionDirective라는 사용자 정의 지시자를 정의하여 권한 검증 로직을 수행하는 예시입니다. 이 예시에서는 User 객체가 필요한 권한 검증 로직을 수행하며, 권한이 없는 경우 MyGraphQLError를 던지도록 구현되어 있습니다.

결론

아폴로 서버를 사용하면 인증과 권한 관리를 효율적으로 구현할 수 있습니다. 인증을 위해 context를 활용하고, 권한 관리를 위해 사용자 정의 지시자를 활용하는 방법을 살펴보았습니다. 이를 기반으로 안전하고 보안적인 GraphQL API를 구축할 수 있습니다.