DOCS/journey/troubleshooting/251117_admin_dashboard_routing_implementation.md
happybell80 06030d536f docs: Admin Dashboard 라우팅 구현 트러블슈팅 문서
배경:
- /admin 접근 시 빈 페이지 (Gateway 404)

해결:
- Gateway에 /admin → frontend-base(8000) 프록시 추가
- JWT 검증 중앙화 유지
- TDD 방식으로 테스트 먼저 작성

아키텍처:
- Gateway: 인증 + 라우팅
- frontend-base: 관리자 UI
- 역할 분리 명확화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 15:00:09 +09:00

5.8 KiB

Admin Dashboard 라우팅 구현 (Gateway 프록시 패턴)

날짜: 2025-11-17
작업자: Claude (51123 서버 관리자)
관련 서버: 51123
관련 서비스: robeing-gateway, frontend-base, nginx


배경

사용자가 https://ro-being.com/admin으로 관리자 대시보드 접근 시 빈 페이지가 표시되는 문제 발생.

초기 상태

  • nginx: /adminlocalhost:8100 (robeing-gateway)
  • robeing-gateway: /admin 라우팅 없음 → 404 반환
  • frontend-base: localhost:8000에서 실행 중, /admin UI 제공

문제 원인

robeing-gateway는 로빙 API 라우팅 전용으로 설계되어 /admin 경로를 처리하지 않음.


해결 방안 검토

방안 1: nginx에서 직접 frontend-base로 프록시

location /admin {
    proxy_pass http://localhost:8000;
}

문제점:

  • JWT 검증 불가 (인증 없이 접근 가능)
  • frontend-base가 51124 robeing-monitor 데이터 조회 시 인증/UUID 변환 로직 중복 필요

방안 2: Gateway에 /admin 라우팅 추가 (채택)

@app.api_route("/admin/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def admin_proxy(
    path: str,
    request: Request,
    user_uuid: str = Depends(get_verified_user)
):
    """Admin dashboard - proxy to frontend-base (51123:8000)"""
    frontend_base_url = "http://localhost:8000"
    target_url = f"{frontend_base_url}/admin/{path}" if path else f"{frontend_base_url}/admin"
    
    logger.info(f"Admin request from user {user_uuid} to {target_url}")
    
    async with httpx.AsyncClient() as client:
        response = await client.request(
            method=request.method,
            url=target_url,
            headers=dict(request.headers),
            content=await request.body()
        )
        
        return Response(
            content=response.content,
            status_code=response.status_code,
            headers=dict(response.headers)
        )

장점:

  • JWT 검증 중앙화 유지
  • frontend-base가 Gateway의 인증/UUID 변환 활용 가능
  • 역할 분리 명확: Gateway(인증+라우팅), frontend-base(UI)

구현 내역

1. robeing-gateway 코드 수정

파일: /home/admin/robeing-gateway/app/main.py

변경 사항:

  1. Import 추가 (line 7):

    from fastapi.responses import JSONResponse, Response
    
  2. /admin 라우팅 추가 (line 392-417):

    • JWT 검증: get_verified_user() Dependency 적용
    • frontend-base(localhost:8000)로 프록시
    • 모든 HTTP 메서드 지원 (GET, POST, PUT, DELETE)

2. Gateway 재시작

cd /home/admin/robeing-gateway
docker compose down && docker compose up -d --build

3. 테스트 코드 작성

파일: /home/admin/frontend-base/tests/test_admin_api.py

테스트 케이스:

  1. Gateway /admin - JWT 없음 → 401 예상
  2. frontend-base /health → 200 OK
  3. frontend-base /admin 직접 접근 → HTML 반환

실행 결과:

=== Test 1: Gateway /admin without JWT (예상: 401) ===
Status: 401
✅ JWT 검증 작동 확인

=== Test 2: frontend-base /health ===
Status: 200
✅ frontend-base 정상

=== Test 3: frontend-base /admin (직접 접근) ===
Status: 200
Content-Type: text/html; charset=utf-8
✅ Admin UI 정상

✅ 모든 테스트 통과

아키텍처 플로우

Before (404 에러)

사용자 → nginx → robeing-gateway → 404 (라우팅 없음)

After (정상 동작)

사용자 → nginx (:80/443) → robeing-gateway (:8100)
         ↓ JWT 검증
         ↓ user_uuid 추출
         → frontend-base (:8000) → Admin UI 반환

frontend-base가 robeing-monitor 데이터 조회 시

사용자 → Gateway (:8100/admin)
         → frontend-base (:8000)
            → Gateway (:8100/api/stats) ← JWT 재사용
               → robeing-monitor (:9024, 51124 서버)

검증

1. Gateway 상태

docker ps --filter "name=robeing-gateway"
# 출력: Up X seconds (healthy)

2. 엔드포인트 테스트

# JWT 없이 (401 예상)
curl http://localhost:8100/admin
# {"detail":"Missing or invalid authorization header"}

# JWT 포함 (200 OK, HTML 반환)
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8100/admin
# <!DOCTYPE html>...

3. 브라우저 테스트

  • URL: https://ro-being.com/admin
  • 예상: Admin Dashboard UI 표시
  • JWT 자동 포함 (localStorage에서)

설계 원칙 (Gateway Proxy Pattern)

Gateway의 역할 (중앙집중형)

  1. JWT 검증: 모든 요청의 인증 게이트웨이
  2. Username → UUID 변환: DB 조회 및 캐싱
  3. 라우팅:
    • /api/chat → 로빙 서비스 (rb8001, rb10508 등)
    • /api/stats → robeing-monitor (51124:9024)
    • /api/items → robeing-monitor
    • /admin → frontend-base (51123:8000)

역할 분리

  • robeing-gateway: 인증 + 라우팅 (코드 없는 프록시)
  • frontend-base: 관리자 UI + 시스템 메트릭 대시보드
  • robeing-monitor: 로빙 통계, 아이템 관리 (51124)

관련 문서

  • Gateway 아키텍처: /home/admin/DOCS/book/300_architecture/gateway_proxy_patterns.md
  • 전체 시스템 구조: /home/admin/DOCS/book/300_architecture/310_전체_시스템_구조_컨테이너와_마이크로서비스.md
  • Gateway 구현 히스토리: /home/admin/DOCS/journey/troubleshooting/250809_happybell80_robing-gateway구현.md

교훈

설계 검증의 중요성

  • 새 서비스 추가 시 기존 Gateway 라우팅 검토 필수
  • 각 서비스의 역할 명확히 문서화

TDD 접근

  • 테스트 코드 먼저 작성 (tests/test_admin_api.py)
  • 구현 → 테스트 → 검증 순서 준수

일관성 있는 인증

  • 모든 보호된 엔드포인트는 Gateway 경유
  • JWT 검증 로직 중앙화로 보안 강화