diff --git a/troubleshooting/250811_happybell80_Gateway필드변환문제.md b/troubleshooting/250811_happybell80_Gateway필드변환문제.md new file mode 100644 index 0000000..24f9475 --- /dev/null +++ b/troubleshooting/250811_happybell80_Gateway필드변환문제.md @@ -0,0 +1,137 @@ +# Gateway 필드 변환 및 보안 문제 해결 + +## 오전 10:58 + +### 문제 1: 헬스체크 엔드포인트 표준화 + +**상황**: +- 각 서비스마다 다른 헬스체크 엔드포인트 +- nginx/k8s 표준인 `/healthz` 필요 + +**해결**: +```python +# rb10508_micro/app/main.py +@app.get("/healthz") +async def healthz(): + """단순 헬스체크 - 서비스 생존 확인만""" + return {"status": "ok"} +``` +- 루트 레벨에 `/healthz` 추가 +- API 프리픽스 없이 접근 가능 +- 빠른 응답 (< 100ms) + +### 문제 2: UUID 형식 오류 + +**원인**: +- Frontend가 username(`happybell80`) 전송 +- Gateway가 UUID 형식 기대 +- `invalid UUID 'happybell80': length must be between 32..36 characters` + +**해결**: +```python +# robeing-gateway/app/database.py +async def get_robing_info(username: str): + """username으로 직접 조회""" + query = text(""" + SELECT ... + FROM workspace_members wm + JOIN users u ON wm.user_id = u.id + WHERE u.username = :username + """) +``` +- users 테이블 JOIN으로 username → UUID 변환 +- UUID 체크 로직 제거 (Frontend는 항상 username 사용) + +### 문제 3: nginx 직접 프록시 vs Gateway 라우팅 + +**현재 구조 분석**: +``` +# 원래 설계 (문서) +Frontend → nginx(/gateway/) → Gateway(8100) → rb10508_micro + +# 실제 nginx 설정 +location ^~ /rb10508/ { + proxy_pass http://192.168.219.52:10508/; # 직접 프록시 +} +location ^~ /gateway/ { + proxy_pass http://localhost:8100/; # Gateway 서비스 +} +``` + +**문제점**: +- `/rb10508/`는 Gateway 우회 +- `message` → `text` 필드 변환 안됨 +- 422 Unprocessable Entity 에러 + +**해결 방안 검토**: +1. nginx 모든 요청을 Gateway로 → **Gateway 부하 문제** +2. rb10508_micro가 두 필드 모두 지원 → **실용적** + +### 문제 4: 사용자 인증 검증 부재 (보안 위험) + +**현재 상황**: +```javascript +// 누구나 헤더 조작 가능 +fetch('/gateway/api/chat', { + headers: {'X-User-Id': 'admin'} // 위장 가능! +}) +``` + +**위험**: +- 사용자 위장 가능 +- 로빙 접근 권한 우회 +- 데이터 유출 위험 + +**필요한 조치**: +- JWT 토큰 검증 로직 추가 +- auth-server와 연동 +- 실제 사용자 확인 필수 + +## 교훈 + +### 1. **헬스체크 설계** +- 표준 엔드포인트 사용 (`/healthz`) +- 빠른 응답 우선 (복잡한 체크는 별도 엔드포인트) +- 루트 레벨 배치로 프리픽스 문제 회피 + +### 2. **식별자 설계** +- Frontend는 사용자가 이해하는 값 사용 (username) +- Backend에서 내부 ID 변환 +- UUID는 내부용으로만 사용 + +### 3. **Gateway 아키텍처** +- 모든 요청을 Gateway로 보내면 병목 발생 +- 실용적 접근: 서비스가 유연하게 처리 +- 점진적 마이그레이션 전략 필요 + +### 4. **보안 최우선** +- 헤더 기반 인증은 위험 +- JWT 토큰 검증 필수 +- 신뢰 경계 명확히 설정 + +## 현업 패턴 + +### Gateway 부하 해결: +1. **Service Mesh**: 각 서비스에 Sidecar 프록시 +2. **Gateway 클러스터링**: 여러 Gateway 인스턴스 +3. **하이브리드**: 중요 요청만 Gateway, 나머지 직접 + +### 실용적 해결: +```python +class MessageRequest(BaseModel): + text: Optional[str] = None + message: Optional[str] = None + + def get_text(self): + return self.text or self.message +``` +- 두 경로 모두 지원 +- Gateway 유무와 관계없이 작동 +- 마이그레이션 유연성 확보 + +## 다음 작업 + +1. **즉시**: rb10508_micro에 message 필드 지원 추가 +2. **긴급**: JWT 토큰 검증 구현 +3. **계획**: Gateway 스케일링 전략 수립 +4. **장기**: Service Mesh 도입 검토 \ No newline at end of file