Backend Engineering

Kong Gateway 활용 - 인증과 인가 분리

zamezzz 2025. 7. 23. 18:25

오늘은 Kong Gateway를 활용하여 인증과 인가를 분리한 내용에 대해서 정리해보려고 합니다.

Kong Gateway가 무엇이고, 어떤 장점이 있는지는 이전 글을 참고해주시면 됩니다!

( Kong Gateway를 써보자 - 인증, 라우팅, 보안까지 한 번에! )

 

✅ 인증(Authentication)과 인가(Authorization)의 개념

먼저 인증과 인가의 차이를 짚고 넘어가겠습니다.

  • 인증(Authentication): "누구인지"를 확인하는 절차입니다.
    사용자가 올바른 자격 증명(아이디/비밀번호, 토큰 등)을 가지고 있는지를 판단합니다.
  • 인가(Authorization): "무엇을 할 수 있는지"를 결정합니다.
    인증된 사용자가 특정 자원 또는 기능에 접근할 권한이 있는지를 판단합니다.

👉 예를 들어, 로그인을 성공한 사용자가 관리자 기능을 사용할 수 있는지는 '인가'의 문제입니다.

 

 

✅ 인증(Authentication)과 인가(Authorization)를 왜 분리해야 할까?

많은 시스템에서는 인증과 인가를 동일한 서버에서 처리하지만, 다음과 같은 이유로 분리하는 구조가 더 나은 선택이 될 수 있습니다

제가 생각한 가장 큰 이유는 성능 최적화에 있었습니다.

Kong에서는 인증과 라우팅에만 최선을 다해 진행하고, 이후 로직은 다른 서버들에게 맡겨 성능을 최대한 끌어올리자는 목적이 있었고,

그 외에는 로직 분리와 인가 정책의 유연성을 위한 측면이 있었습니다.

  • 관심사의 분리 (Separation of Concerns)
    인증 서버는 사용자 식별에만 집중, 인가 서버는 정책과 권한 로직에만 집중합니다.
  • 스케일링과 성능 최적화
    인증은 대부분 로그인 시 1회 처리, 인가는 요청마다 반복됩니다.
    인가 서버만 따로 스케일링하면 성능을 더 유연하게 조절할 수 있습니다.
  • 정책의 유연성 확보
    인가 정책은 복잡해질 수 있습니다.
    예: 사용자 역할(Role), 조직 단위, 구독 플랜, 리소스별 세부 권한 등.

그래서 실제 구현할 때는 아래와 같은 구조로 진행을 했습니다.

Kong은 강력한 인증 플러그인을 제공하지만, 인가 정책까지 모든 걸 맡기기엔 복잡한 권한 로직을 적용하기 어려웠습니다.

그래서 Kong에서는 인증까지만 처리하고, 인가는 API 서버 내부 로직으로 처리했습니다.
권한 캐시는 Redis를 활용해 속도도 확보했습니다.

 

인가 서버 구성 방식과 이점

간단한 샘플 코드와 함께 방식을 설명하겠습니다.

1. Kong에서는 JWT 토큰 검증만 수행

토큰 유효성 검사 후, 유저 정보(userId, role)를 HTTP Header에 담아 백엔드로 전달합니다.

2. 인가 서버에서는 이 정보로 인가 판단
백엔드에서는 해당 유저가 요청한 리소스를 사용할 권한이 있는지 검사합니다.

@RestController
@RequestMapping("/v1/projects")
class ProjectController(
    private val authService: AuthorizationService
) {

    @GetMapping("/{projectId}")
    fun getProject(
        @RequestHeader("X-User-Id") userId: String,
        @PathVariable projectId: String
    ): ResponseEntity<ProjectDto> {
        if (!authService.hasAccess(userId, projectId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build()
        }

        val project = ... // project fetch logic
        return ResponseEntity.ok(project)
    }
}

 

 

 

이런 식으로 진행을 하고, API별 공통 로직이므로 별도 Annotation을 만들어 사용했습니다.

실제 권한 정보가 업데이트 되기 전에는 redis를 통해 권한 정보를 획득하였고,

어드민 등에서 권한정보 업데이트 시 캐시도 별도로 업데이트를 진행하였습니다.

 

 정리하며...

Kong Gateway는 인증을 비롯한 여러 기능을 쉽게 구현하고 운영할 수 있습니다. (Plugin을 통해)
하지만 인가까지 위임하기엔 정책의 복잡성, 서비스별 유연한 대응이 어렵습니다. 서비스에 따라 복잡한 권한 정책을 가질 수 있고,

운영에서 요구하는 스펙은 지속적으로 확장될 수 있기 때문이죠....

 

따라서 인증은 Kong, 인가는 백엔드 서버에서 수행하는 구조는 서비스 구현은 물론 운영의 측면에서도 충분히 장점이 있습니다.

 

그럼 오늘 글은 여기서 마치겠습니다.

감사합니다.