Skip to content

실시간 대화분석 500 오류 문제해결 #61

@Tae4an

Description

@Tae4an

📋 문제 개요

Flutter 앱에서 실시간 대화분석 종료 시 500 Internal Server Error 발생

  • 세션 ID 조회 실패로 인한 분석 결과 생성 불가
  • 마이크로서비스 간 통신 인증 문제

🕐 문제 발생 타임라인 및 해결 과정

1️⃣ 초기 문제 발견 (세션 ID: 982ad42c-05ef-432d-92ac-c9050d72f36c)

문제: 세션 종료 시 500 오류 발생

# 로그에서 발견된 오류
Session not found for ID: 982ad42c-05ef-432d-92ac-c9050d72f36c

2️⃣ 인증 문제 발견

문제: realtime-service에서 session-service 호출 시 401 Unauthorized 오류 반복 발생

# 서버 로그
401 Unauthorized - INTER_SERVICE_TOKEN 누락

원인:

  • GitHub Secrets에는 INTER_SERVICE_TOKEN 존재
  • GitHub Actions 워크플로우에서 .env 파일 생성 시 해당 토큰 누락

해결:

# .github/workflows/raspberry-pi-deploy.yml (라인 809)
echo "INTER_SERVICE_TOKEN=${{ secrets.INTER_SERVICE_TOKEN }}" >> .env

3️⃣ MongoDB 의존성 문제

문제: session-service 재시작 루프 및 "Cannot find module 'mongodb'" 오류

# 컨테이너 로그
Error: Cannot find module 'mongodb'

원인: api/session-service/src/config/mongodb.js에서 MongoDB 사용하지만 package.json에 의존성 누락

해결:

// api/session-service/package.json
{
  "dependencies": {
    "mongodb": "^6.3.0"
  }
}

4️⃣ realtime-service 인증 헤더 누락

문제: realtime-service에서 다른 서비스 호출 시 Authorization 헤더 누락

// 기존 코드 - 인증 헤더 없음
headers: {
    'X-Service-Name': 'realtime-service',
    'Content-Type': 'application/json'
}

해결:

// api/realtime-service/src/utils/serviceClient.js
headers: {
    'X-Service-Name': 'realtime-service',
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.INTER_SERVICE_TOKEN}`
}

5️⃣ session-service 라우팅 인증 충돌

문제: POST /api/v1/sessions 엔드포인트에서 JWT 토큰만 지원, 서비스 토큰 거부

# 세션 ID들에서 반복 발생
6bbfc26b-6689-4620-a7b9-889f9e71ea9b: 401 Unauthorized
844abea1-2fe6-4dd3-a1cc-5ec6790e6d51: 401 Unauthorized

해결: 동적 인증 라우팅 구현

// api/session-service/src/routes/sessions.js
router.post('/', (req, res, next) => {
    const authHeader = req.headers.authorization;
    if (!authHeader) return res.status(401).json({success: false, message: '인증 토큰이 필요합니다'});

    const token = authHeader.split(' ')[1];
    const serviceToken = process.env.INTER_SERVICE_TOKEN;

    if (token === serviceToken) {
        return authMiddleware.validateServiceToken(req, res, next);
    } else {
        return authMiddleware.verifyToken(req, res, next);
    }
});

6️⃣ JWT 인증 미들웨어 누락

문제: 여러 Private 엔드포인트에 인증 미들웨어 누락으로 req.user undefined 발생

# 세션 ID: 5503a06d-5420-4027-b6fd-c5532c168edb
TypeError: Cannot read properties of undefined (reading 'id')

해결: 모든 Private 엔드포인트에 authMiddleware.verifyToken 추가

// 예시: GET /api/v1/sessions/:id
router.get('/:id', authMiddleware.verifyToken, sessionController.getSessionById);

7️⃣ JWT 토큰 검증 최적화

문제: auth-service 의존성으로 인한 추가 인증 실패

# 세션 ID: d241bce9-0878-4cfe-aaba-ed13e0ea19c9
Cannot read properties of undefined (reading 'id')

해결: JWT 자체 검증으로 단순화

// api/session-service/src/middleware/auth.middleware.js
// auth-service 검증 단계 임시 비활성화
const decoded = jwt.verify(token, process.env.JWT_ACCESS_SECRET);
req.user = {
    ...decoded,
    id: decoded.sub  // sub 필드를 id로 설정
};

최종 결과

성공 사례 (세션 ID: a4bec67e-1298-4eca-bd5f-7c63827834f1)

✅ 세션 종료 처리 성공: 2개 세그먼트 분석 완료
✅ 새 분석 결과 생성 성공
✅ 기존 리포트 발견: 684479128de062b1aaf79be8

📊 해결된 주요 기능들

  1. 세션 생성/조회/종료 - 정상 작동
  2. 실시간 음성 처리 - STT WebSocket 연결 성공
  3. 분석 데이터 저장 - 세그먼트별 저장 완료
  4. 분석 결과 조회 - API 응답 정상
  5. Apple Watch 연동 - 햅틱 피드백 정상

핵심 교훈

1. 마이크로서비스 인증 체계

  • 서비스 간 통신용 INTER_SERVICE_TOKEN 필수
  • 사용자 인증용 JWT와 서비스 인증 분리 필요

2. 배포 파이프라인 검증

  • GitHub Secrets 설정만으론 부족
  • 실제 .env 파일 생성 과정 확인 필수

3. 의존성 관리

  • 코드에서 사용하는 모든 패키지 package.json에 명시
  • 컨테이너 환경에서 의존성 누락 시 런타임 오류 발생

4. 인증 미들웨어 일관성

  • Private 엔드포인트는 반드시 인증 미들웨어 적용
  • req.user 객체 의존 로직 사전 검증 필요

앞으로의 개선사항

  1. 모니터링 강화: 서비스 간 통신 실패 알림 시스템
  2. 테스트 자동화: 인증 시나리오별 E2E 테스트
  3. 문서화: 마이크로서비스 인증 아키텍처 문서 작성
  4. 로깅 개선: 더 상세한 오류 컨텍스트 로깅

총 해결 시간: 약 3시간

핵심 수정 파일: 6개

해결된 오류: 500 Internal Server Error → 200 OK** 🎉

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions