# Gateway Admin API 라우팅 및 JWT 검증 문제 해결

**날짜**: 2025-11-17  
**작성자**: admin  
**관련 파일**: 
- `robeing-gateway/app/routers/admin.py`
- `robeing-gateway/app/main.py`
- `robeing-gateway/docker-compose.yml`

---

## 문제 상황

Admin Dashboard를 표준 배포 방식으로 전환하면서 Gateway를 통한 API 프록시가 필요했으나, 다음 문제들이 발생:

1. Gateway에서 admin API 요청이 404 오류 발생
2. 로그인 후 JWT 토큰 검증 실패 (401 Unauthorized)
3. Docker 컨테이너 간 통신 문제

## 해결 방안

### 1. Gateway Admin Router 등록

**문제**: `/admin/api/*` 요청이 Gateway에서 처리되지 않음

**원인**: 
- `robeing-gateway/app/routers/admin.py`의 router가 제대로 등록되지 않음
- router prefix 설정 문제

**해결**:
- `robeing-gateway/app/main.py:92`: `app.include_router(admin.router, prefix="")` 추가
- `robeing-gateway/app/routers/admin.py:17`: `router = APIRouter()` (prefix 없음)
- `robeing-gateway/app/routers/admin.py:22`: `/admin/api/{path:path}` 라우트 정의

**검증**:
```bash
sudo docker exec robeing-gateway python -c \
  "from app.main import app; print([r.path for r in app.routes if 'admin' in r.path])"
# ['/admin/api/{path:path}']
```

### 2. Docker 네트워크 내부 통신 문제

**문제**: Gateway 컨테이너에서 `localhost:8000`으로 접근 시 자기 자신을 가리킴

**원인**: 
- Docker 컨테이너 내부에서 `localhost`는 컨테이너 자신을 의미
- 다른 컨테이너에 접근하려면 컨테이너 이름 또는 네트워크 IP 사용 필요

**해결**:
- `robeing-gateway/app/routers/admin.py:20`: `ADMIN_BACKEND_URL = "http://admin-dashboard-backend:8000"` (localhost → 컨테이너 이름)

**교훈**:
- Docker 컨테이너 간 통신은 `localhost`가 아닌 컨테이너 이름 사용
- 같은 Docker 네트워크(`appnet`)에 있는 컨테이너는 이름으로 자동 DNS 해석됨

### 3. JWT Secret Key 불일치 문제

**문제**: 로그인은 성공하지만 이후 API 호출 시 401 Unauthorized 오류

**원인**:
- Gateway의 JWT_SECRET_KEY와 admin-dashboard backend의 SECRET_KEY가 불일치
- Gateway: `.env` 파일의 `JWT_SECRET_KEY=9cc562b6296b87b02dd89045a2e7e11c249713a59a5ac0160d852121f1289664`
- Backend: `admin-dashboard/backend/admin_routes.py:32`의 `SECRET_KEY = "admin_secret_key_robeing_2025"`

**에러 로그**:
```
2025-11-17 19:36:23,945 - app.core.auth - ERROR - JWT verification failed: Not enough segments
{"detail":"Token validation failed: Signature verification failed."}
```

**해결**:
- `robeing-gateway/docker-compose.yml:8`: `JWT_SECRET_KEY=admin_secret_key_robeing_2025` 환경변수 추가
- Gateway 재빌드: `docker compose down && docker compose up -d --build`

**검증**:
```bash
TOKEN=$(curl -s -X POST http://localhost:8000/admin/login \
  -H "Content-Type: application/json" \
  -d '{"password":"19800508"}' | python3 -c \
  "import sys, json; print(json.load(sys.stdin)['access_token'])")

curl -X GET http://localhost:8100/admin/api/system/overview \
  -H "Authorization: Bearer $TOKEN"
# {"timestamp":"2025-11-17T10:37:21.154596","cpu":{"percent":4.6,...},...}
```

**교훈**:
- JWT 검증을 위해서는 발급 서버와 검증 서버의 secret key가 반드시 일치해야 함
- Docker Compose의 `environment` 섹션으로 `.env` 파일의 환경변수 오버라이드 가능

## 교훈

- Docker 컨테이너 간 통신은 `localhost`가 아닌 컨테이너 이름 사용
- JWT 검증을 위해서는 발급 서버와 검증 서버의 secret key 반드시 일치 필요
- Gateway Router 등록 시 prefix 명시 필요
