728x90

API Gateway + 인증 게이트 구조
기본 구조는 이렇게 됩니다.
[Client / Browser]
│ (HTTP, HTTPS)
▼
[Kong Gateway] ← (Auth Plugin / Custom Plugin / Session Plugin)
│
├─ /auth → Auth Service (로그인/로그아웃, 세션 생성)
├─ /app1 → App1 Service
├─ /app2 → App2 Service
└─ /app3 → App3 Service
여기서 중요한 포인트
- Kong이 모든 서비스 앞에 서 있는 “인증 게이트” 역할
- 도메인/서브도메인 동일 → 쿠키 기반 SSO 가능
- 세션 정보는 Redis 등 공용 저장소에 저장 → 모든 요청에서 공통 검증
- 백엔드 서비스는 “인증 완료된 사용자 정보만 헤더로 전달받고 사용”
→ 각 서비스는 “인증 로직 최소화” + “권한(Authorization)에만 집중”
두 가지 큰 인증 패턴
Kong으로 구현하는 인증은 크게 두 축으로 보면 이해가 쉽습니다.
- API 인증 패턴 – 서비스 간 호출, 외부 파트너 API, 머신 to 머신에 적합
- Basic Auth
- Key Auth(API Key)
- JWT
- OAuth2 / OIDC (토큰 기반)
- 웹 SSO 패턴 – 사용자가 브라우저로 로그인하고 여러 웹 서비스 이용
- 세션 + 쿠키 + Redis
- Kong Session Plugin 또는 Custom Plugin / Nginx+Lua
실무에서는 보통 이렇게 조합합니다.
- 내부/외부 시스템 API → Key-Auth 또는 JWT
- 내부 관리자·업무 포털 → SSO (세션+쿠키)
- 외부 IdP(Azure AD, Keycloak 등)와 연계 → OIDC + 세션
기본 docker-compose 구성 요소
kong-database(PostgreSQL)
→ Kong 설정, 서비스/라우트/플러그인 메타데이터 저장kong
→ 게이트웨이 본체. 플러그인 실행 위치redis
→ 세션 정보(로그인 사용자 정보, TTL 등) 저장소auth-service
→ 로그인/로그아웃 처리, 세션 생성·삭제,/auth/login,/auth/logout,/auth/verifyapp1,app2,app3
→ 실제 업무 서비스들
보안 관점 체크포인트
- Redis에 직접 접근 가능한 네트워크 범위 제한 (Kong / auth-service 만 접근)
- Postgres, Redis 모두 인증/암호 설정 필수
- Kong Admin API(8001)는 내부망 전용 또는 VPN 뒤에 두기 (절대 외부 노출 금지)
Kong 기반 API 인증 패턴 정리
1. Basic Auth
- 헤더:
Authorization: Basic base64(username:password) - Kong 플러그인:
basic-auth
사용 예시
# 서비스에 Basic Auth 플러그인 적용
curl -X POST http://localhost:8001/services/app1-service/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"
# Consumer/계정 생성
curl -X POST http://localhost:8001/consumers \
--data "username=admin"
# 비밀번호 등록
curl -X POST http://localhost:8001/consumers/admin/basic-auth \
--data "username=admin" \
--data "password=secure-password"
보안 관점 조언
- TLS(HTTPS) 필수. 아니면 비밀번호 평문 노출.
- 장기적으로는 API Key / JWT / OIDC로 전환을 권장.
2. Key Auth (API Key)
- 헤더:
apikey: <key>또는X-API-Key: <key> - 플러그인:
key-auth
서비스 적용
curl -X POST http://localhost:8001/services/app1-service/plugins \
--data "name=key-auth" \
--data "config.key_names[]=apikey" \
--data "config.hide_credentials=true"
Consumer/Key 발급
curl -X POST http://localhost:8001/consumers \
--data "username=api-user"
curl -X POST http://localhost:8001/consumers/api-user/key-auth \
--data "key=my-api-key-12345"
보안 관점
- Key는 1인 1키 또는 시스템 별 키로 발급 후, 유출시 폐기 가능하게 운영
- 키 사용 로그를 Kong/ES/Wazuh 등으로 수집 → 사용자·시스템별 호출 추적
3. JWT Authentication
- 토큰:
Authorization: Bearer <JWT> - 플러그인:
jwt
Kong 측
curl -X POST http://localhost:8001/services/app1-service/plugins \
--data "name=jwt"
Consumer에 JWT 자격 생성
curl -X POST http://localhost:8001/consumers/jwt-user/jwt \
--data "algorithm=HS256" \
--data "secret=my-secret-key"
# 응답에서 key (iss), secret 획득
클라이언트 토큰 발급 (Python 예시)
import jwt, time
payload = {
'iss': 'your-key-from-kong',
'exp': int(time.time()) + 3600
}
token = jwt.encode(payload, 'my-secret-key', algorithm='HS256')
print(token)
보안 관점
exp필수. 짧은 TTL + Refresh 토큰 구조 고려- 비밀키(secret)는 Vault/KMS에 보관, 코드 저장소에 넣지 않기
- Claim에 역할, 권한 최소한만 포함 (민감정보 X)
4. OAuth2 / OpenID Connect (OIDC)
- 외부 IdP(Keycloak, Okta, Azure AD 등)와 연동 시 사용
- Kong 플러그인:
oauth2또는openid-connect(엔터프라이즈/커뮤니티)
Keycloak 예시 플로우
- 사용자가
/app1접근 - 인증되지 않으면 → IdP 로그인 페이지로 리다이렉트
- 로그인 성공 → IdP가 Authorization Code + Token 발급
- Kong/백엔드에서 토큰 검증 후 세션/쿠키 생성
OIDC 보안 포인트
- Redirect URI를 정확히 제한 (Open Redirect 방지)
state파라미터 사용으로 CSRF 방지- IdP와의 통신은 https + 공개 키 기반 서명 검증
웹 SSO (세션+쿠키) 구조 상세
이제 가장 중요한 “같은 도메인에서 여러 서비스 SSO” 부분을 정리해보겠습니다.
300x250
1. 핵심 아이디어
- 하나의 로그인 서비스(auth-service) 에서 로그인 처리
- 로그인 성공 시
- 세션 ID 생성 (
session:<username>:<timestamp>) - Redis에 세션 객체 저장 (username, role, name, createdAt, TTL 등)
- 브라우저에
auth_session쿠키 설정 (도메인 전체에 유효)
- 세션 ID 생성 (
- 모든 서비스 요청은 Kong/Nginx에서 쿠키 → Redis → 세션 검증
- 검증 후 X-User-Id, X-User-Role, X-User-Name 헤더로 각 서비스에 전달
2. Auth Service 역할 (Node.js 예시 기반 정리)
Auth Service 주요 엔드포인트
GET /auth/login- 로그인 페이지 렌더링 (HTML 폼)
POST /auth/login- 아이디/비밀번호 검증
- JWT/세션 ID 발급
- Redis에 세션 저장
auth_session쿠키 설정
POST /auth/logout- Redis에서 세션 삭제
- 쿠키 삭제
GET /auth/verify- Kong/게이트웨이가 호출하는 세션 검증용 API
GET /auth/me- 현재 로그인 사용자 정보 조회
보안 관점
- 로그인 시도 실패 횟수 제한 (브루트포스 방지)
- 비밀번호는 반드시
bcrypt등으로 해시 저장 - 관리자 계정은 별도의 강화된 정책 (IP 제한, MFA 등)
3. Kong에서 세션 검증하는 두 가지 방법
① Session 플러그인 + 별도 검증 로직 요청
- Kong Session 플러그인으로 쿠키 관리 + Redis 저장소 연계
/auth/verify엔드포인트와 연계 가능- 상대적으로 구현 난이도 낮음, 플러그인 설정으로 처리
② Custom Plugin (Lua) 직접 구현
사용하신 예시처럼, Lua로 Redis에 직접 연결해서 세션 검증
- 인증 제외 경로
/auth/*,/health,/static등
- 나머지 요청
auth_session쿠키 파싱- Redis에서 세션 조회
- 없으면
/auth/login?redirect=<원래 URL>로 302 리다이렉트 - 있으면 사용자 정보를 헤더에 추가 후 백엔드 호출
보안 체크포인트
- redirect URL 화이트리스트 또는 도메인 체크 (Open Redirect 방지)
- Redis 오류 시 fallback 정책
- FA(“모두 차단”)가 기본. (Redis 장애 → 인증 불가 → 서비스 영향 vs 보안)
- 장애 시 읽기 전용 모드 또는 점검 페이지 안내 고려
4. Nginx + Lua로 직접 구현하는 경우
Kong 없이 Nginx만 쓴다면
access_by_lua_file에서 세션 검증 스크립트 실행- location 블록에서
$auth_passed여부에 따라/auth/login으로 리다이렉트 - 백엔드에는
X-User-*헤더로 사용자 정보 전달
이 방식은 Kong 없이도 작동하지만
- Kong의 장점(플러그인, 관리 UI, 통계, Rate Limiting, Key-Auth 등)을 활용 못함
- 이미 Kong을 도입한다면 Custom Plugin 또는 Kong+Nginx 조합이 더 전략적
백엔드 서비스에서의 처리 방식
각 서비스는 다음 원칙만 지키면 됩니다.
- 인증은 Kong/게이트웨이가 책임진다.
- 서비스는 헤더로 들어온 사용자 정보만 신뢰하고 사용.
- 서비스에서 직접 쿠키/세션을 다루지 않는다. (가능하면)
예: Express.js에서 사용자 정보 활용
app.get('/api/data', (req, res) => {
const userId = req.headers['x-user-id'];
const userRole = req.headers['x-user-role'];
const userName = req.headers['x-user-name'];
// 권한 체크
if (userRole !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
res.json({ message: `Hello ${userName}(${userId})` });
});
보안 관점
- 절대 클라이언트에서 임의 헤더로
X-User-*넣는 상황을 허용하면 안 됨- Kong ↔ Backend 사이 통신은 내부망/전용 네트워크로 고정
- 외부에서 직접 백엔드 접속 불가하게 방화벽·보안그룹 설계
보안 관점 체크리스트
도입 시 내부 개발·운영팀에게 줄 수 있는 점검/가이드 포인트를 정리하면
- Gateway 경로 통제
- 모든 서비스 진입점은 Kong만 사용
- 백엔드 서비스 포트는 외부에서 직접 접근 불가 (FW, SG, NACL 등)
- 쿠키/세션 관리
-
auth_session쿠키HttpOnly,Secure(HTTPS 시),SameSite=Lax/Strict적용 - 세션 TTL 명확히 정의(예: 1시간), Idle Timeout 정책 설정
- 로그아웃 시 세션 즉시 폐기 + 쿠키 삭제
-
- Redis / DB 보안
- Redis는 내부 네트워크에서만 접근 가능
- 필요시 Redis AUTH 사용 및 TLS 적용
- 세션 데이터에 민감정보(비밀번호, 주민번호 등) 저장 금지
- 인증·권한 분리
- 인증(AuthN)은 Gateway / Auth Service에서 처리
- 권한(AuthZ)은 각 서비스에서 헤더 기반으로 처리 (Role, Scope 등)
- 로그·모니터링
- Kong Proxy/Plugin 로그를 중앙 로그 시스템(Elastic, Wazuh, Chronicle 등)으로 수집
- 다음 항목을 최소 수집
- Consumer/사용자 ID
- 요청 URL/메서드
- 응답 코드
- Fail Reason (401/403 사유)
- 이상 징후 탐지
- 특정 계정의 과도한 로그인 실패
- 비정상 API 호출 패턴 (Rate limiting 우회 시도 등)
- 관리 인터페이스 보호
- Kong Admin API, Konga/Kong Manager는 내부망 + VPN + IP 제한
- 별도 관리자 계정과 MFA 적용
- 정책 문서화
- “인증/SSO 표준 아키텍처” 문서
- “서비스 신규 오픈 시 Kong 등록 절차 + 인증 패턴 선택 가이드”
- “Key/JWT 발급·회수 절차”, “권한(Role) 설계 기준”
단계별 도입 로드맵 (실행 순서 요약)
마지막으로, 실제 도입을 한다고 가정하고 “어떻게 진행할지”를 한 번에 볼 수 있게 정리해보면
- 기초 인프라 준비
- Kong + Postgres + Redis + Auth Service + 샘플 App1, App2, App3 docker-compose로 구동
- Kong 서비스/라우트/플러그인 정의
/auth,/app1,/app2,/app3서비스와 라우트 추가- 첫 단계에서는 Key-Auth / Basic-Auth로 API 인증 흐름부터 익히기
- Auth Service 완성
- 로그인/로그아웃, 세션 생성, Redis 저장,
/auth/verify구현
- 로그인/로그아웃, 세션 생성, Redis 저장,
- 세션 기반 SSO 적용
- Kong Session 플러그인 또는 Custom Plugin으로 세션 검증 로직 적용
- 브라우저 기준
/auth/login → /app1 /app2 /app3SSO 동작 확인
- OIDC/외부 IdP 연동 (선택)
- Keycloak 또는 사내 SSO(IdP)와 OIDC 연동
- 외부 계정체계 ↔ Kong ↔ 내부 서비스 SSO 완성
- 운영·보안 가드레일 정비
- 로그 수집 → SIEM(Wazuh, Elastic, Chronicle 등) 연동
- Rate Limiting, IP Restriction, CORS 등 공통 보안 플러그인 설정
- 운영가이드/보안정책 문서화
728x90
그리드형(광고전용)
댓글