kjp0411 님의 블로그

내일배움캠프 단기심화 Java - 본 캠프 Day 63 본문

TIL

내일배움캠프 단기심화 Java - 본 캠프 Day 63

kjp0411 2026. 5. 13. 16:12

TIL - 2026.05.14

오늘 한 일

오늘은 티켓팅 MSA 프로젝트에서 배포 전 보안 흐름을 점검하고, Gateway 기준의 Role 권한 제어와 Club Admin 가입/승인 흐름을 정리했다.

기존에는 각 서비스에서 개별적으로 권한을 판단하거나, 테스트 편의를 위해 일부 서비스의 Security 설정을 permitAll()로 열어둔 상태였다.

하지만 실제 배포 전에는 사용자의 역할에 따라 접근 가능한 API를 명확히 제한해야 하므로, Gateway에서 JWT 토큰을 검증하고 Role 기반으로 요청을 제어하는 방향으로 정리했다.


1. Gateway Role 기반 권한 제어 정리

Gateway는 Keycloak에서 발급한 JWT 토큰을 검증하고, 토큰에 포함된 사용자 Role 정보를 기준으로 API 접근 권한을 판단한다.

이번에 중점적으로 정리한 권한은 다음과 같다.

역할 설명 주요 권한
ADMIN 플랫폼 관리자 클럽 승인, 전체 관리 API 접근
CLUB_ADMIN 클럽 관리자 클럽 생성, 클럽 관련 관리 기능 접근
USER 일반 사용자 예매, 결제, 조회 등 일반 사용자 기능 접근

Gateway 로그를 통해 토큰에서 사용자 ID와 Role이 정상적으로 추출되는 것도 확인했다.

예시 로그:

[GW-USER-CONTEXT] path=/api/users userId=8373cde9-94dc-43fb-bbfa-28996b5fbcc2 roles=ADMIN

이를 통해 Gateway가 요청을 받을 때 인증 정보를 정상적으로 읽고 있으며, 이후 서비스로 X-User-Id 같은 사용자 식별 정보를 전달할 수 있음을 확인했다.


2. Club Admin 가입 및 클럽 승인 흐름 정리

클럽 생성과 승인 흐름도 다시 정리했다.

현재 구조는 다음과 같다.

  1. CLUB_ADMIN 권한을 가진 사용자가 클럽 생성 요청
  2. 클럽 생성 시 관리자 UUID를 함께 전달
  3. 생성된 클럽은 즉시 활성화되지 않고 승인 대기 상태로 저장
  4. ADMIN 권한을 가진 관리자가 클럽 상태를 승인 처리
  5. 승인된 클럽만 이후 경기, 좌석, 예매 등의 흐름에서 정상적으로 사용 가능

즉, 클럽 관리자가 임의로 클럽을 생성할 수는 있지만, 실제 서비스에서 사용되기 위해서는 플랫폼 관리자의 승인이 필요하다.

이 구조는 운영 관점에서 안전하다.

클럽 관리자가 잘못된 클럽을 생성하더라도, 관리자 승인 단계를 통해 서비스에 반영되기 전에 검증할 수 있기 때문이다.


3. Postman 테스트 흐름 정리

클럽 생성 테스트에서는 Club Admin 토큰을 사용하고, 요청 Body에는 클럽 관리자 UUID를 전달했다.

클럽 생성 응답에서 clubId를 Postman Collection Variable로 저장하도록 테스트 스크립트도 정리했다.

console.log("Club create status:", pm.response.code);
console.log("Club create response:", pm.response.text());

pm.test("Response should not be 401", function () {
    pm.response.to.not.have.status(401);
});

pm.test("Response should not be 403", function () {
    pm.response.to.not.have.status(403);
});

const json = pm.response.json();

if (json.id) {
    pm.collectionVariables.set("clubId", json.id);
}

if (json.data && json.data.id) {
    pm.collectionVariables.set("clubId", json.data.id);
}

이렇게 저장한 clubId는 이후 클럽 승인, 경기 생성, 좌석 생성 등의 테스트 흐름에서 재사용할 수 있다.


4. 배포 전 설정값 관리 점검

배포 전 .env.example 파일도 점검했다.

현재 Git에는 실제 비밀번호나 토큰이 아닌 예시값만 올라가도록 구성되어 있다.

예시:

POSTGRES_DB=ticketing
POSTGRES_USER=ticketing
POSTGRES_PASSWORD=change-me-local

KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=change-me-local

중요한 점은 .env.example은 공유용 템플릿이고, 실제 배포 환경의 민감 정보는 별도로 분리해야 한다는 것이다.

배포 환경에서는 다음과 같이 관리하는 방향이 적절하다.

  • Git에는 .env.example만 업로드
  • 실제 .env 파일은 서버 내부에서만 관리
  • 운영용 DB 비밀번호, Keycloak 관리자 비밀번호, JWT 관련 설정은 외부에 노출하지 않음
  • 추후에는 AWS Secrets Manager, Parameter Store 같은 Secret 관리 도구로 확장 가능

면접이나 프로젝트 설명에서는 다음과 같이 말할 수 있다.

로컬 개발 환경에서는 .env.example을 통해 필요한 환경변수 목록만 공유하고, 실제 배포 환경에서는 민감 정보를 Git에 올리지 않고 서버 환경변수 또는 별도 Secret 관리 방식으로 분리했습니다.


5. 배포 준비 상황

현재는 Docker Compose를 통해 로컬에서 전체 서비스를 한 번에 실행하고, Gateway를 거쳐 API 통합 테스트까지 가능한 상태다.

확인된 흐름은 다음과 같다.

  • Keycloak 기반 JWT 발급
  • Gateway JWT 검증
  • Gateway Role 기반 권한 체크
  • Eureka 기반 서비스 디스커버리
  • Config Server 기반 설정 관리
  • Club Admin 기반 클럽 생성
  • Admin 기반 클럽 승인
  • 경기 생성
  • 좌석 등급 생성
  • 좌석 생성
  • 대기열 생성 및 입장
  • 예매 생성
  • 결제 생성

이제 배포 전에는 다음 항목을 추가로 점검하면 된다.

  • 운영용 .env 분리
  • Docker Compose 파일을 인프라/서비스 기준으로 분리
  • RDS 연결 설정 확인
  • Gateway 외부 공개 포트 정리
  • Keycloak issuer-uri / jwk-set-uri 배포 환경 기준으로 수정
  • Actuator / Prometheus / Grafana 모니터링 확인
  • 불필요한 서비스 포트 외부 노출 제거

오늘 배운 점

오늘 가장 크게 정리한 부분은 인증과 인가의 역할 분리다.

인증은 Keycloak과 Gateway에서 처리하고, 인가는 Gateway에서 Role 기반으로 우선 제어하는 구조로 가져가면 각 서비스의 보안 책임을 줄일 수 있다.

또한 단순히 API가 정상 동작하는 것뿐만 아니라, 누가 어떤 API를 호출할 수 있는지까지 정리해야 실제 배포 가능한 서비스에 가까워진다는 점을 다시 확인했다.

특히 클럽 생성과 승인 흐름은 단순 CRUD가 아니라 운영 정책이 반영된 기능이다.

CLUB_ADMIN은 클럽을 생성할 수 있지만, 최종 승인은 ADMIN만 할 수 있도록 분리함으로써 서비스 운영 안정성을 높일 수 있다.


내일 할 일

  • Gateway 권한 설정 최종 점검
  • API 명세서 기준으로 Role별 접근 가능 API 정리
  • Docker Compose 파일 인프라/서비스 기준으로 분리
  • 배포용 .env 구성
  • RDS 연결 테스트
  • EC2 또는 단일 인스턴스 환경에서 1차 배포 진행
  • 배포 후 Gateway를 통한 API 통합 테스트 진행