1. 문제 상황

혼잡도 조회 api 호출 후 발생한 오류 메세지

 

  • 현상: 지하철 혼잡도 조회 시 백엔드 터미널에 MISSING_AUTHENTICATION_TOKEN (code: gw, id: 403) 에러 발생.
  • 의미: SK Open API 서버가 요청을 받았으나, 헤더에 필수 인증 정보인 appKey가 누락되었음을 의미함.
  • 특이사항: .env 파일에 분명히 SK_API_KEY가 존재함에도 불구하고 발생.

2. 원인 분석 

조사 결과, 단순히 키가 없는 것이 아니라 환경 변수를 로드하는 시점과 경로에 복합적인 문제가 있었습니다.

  1. 환경 변수 로드 경로 오류: dotenv.config()는 기본적으로 프로세스 실행 위치(CWD)에서 .env를 찾습니다. 루트 디렉토리에서 서버를 실행할 경우 backend/.env를 찾지 못해 process.env.SK_API_KEY가 undefined가 됨.
  2. 모듈 로드 순서(Race Condition): index.ts에서 API 관련 모듈(skApi)을 먼저 임포트한 뒤에 dotenv.config()를 호출함. 이로 인해 axios 인스턴스가 생성되는 시점에는 아직 환경 변수가 메모리에 올라오지 않아 빈 값이 할당됨.
  3. 에러 가시성 부족: 기존 코드에서 API 에러의 상세 응답 내용을 로깅하지 않아, 어떤 값이 누락되었는지 즉각적인 파악이 어려웠음.

3. 해결 방법

① 환경 변수 로드 방식 개선 (backend/src/config/api.ts)

실행 위치에 상관없이 항상 .env를 읽어올 수 있도록 절대 경로를 사용하고, appKey 헤더 설정을 보장합니다.

TypeScript
 
import axios from 'axios';
import dotenv from 'dotenv';
import path from 'path';

// 현재 파일 위치 기준, backend 폴더의 .env를 명시적으로 로드
dotenv.config({ path: path.resolve(__dirname, '../../.env') });

const SK_API_KEY = process.env.SK_API_KEY;

export const skApi = axios.create({
  baseURL: 'https://apis.openapi.sk.com/',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'appKey': SK_API_KEY || '', // 로드된 키를 헤더에 주입
  },
});

② 서버 엔트리 포인트 수정 (backend/src/index.ts)

다른 모든 모듈(특히 API 관련 모듈)이 임포트되기 전에 최상단에서 환경 변수를 먼저 로드하도록 수정했습니다.

TypeScript
 
// 반드시 다른 import들보다 위에 위치해야 함
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({ path: path.resolve(__dirname, '../.env') });

import express from 'express';
// ... 이후 나머지 routes 및 middleware 임포트

③ 에러 핸들링 강화 (backend/src/services/CongestionService.ts)

외부 API 오류 발생 시 상세 메시지를 터미널에 출력하여 추후 대응이 쉽도록 개선했습니다.

TypeScript
 
} catch (error: any) {
  const errorMessage = error.response?.data?.message || error.message;
  console.error('Error fetching congestion data from SK API:', errorMessage);
  throw new Error(`SK API 오류: ${errorMessage}`);
}

4. 결과 확인 (Verification)

  • 서버 재시작 후 로그에 Critical Error: SK_API_KEY is not defined가 뜨지 않는지 확인.
  • 혼잡도 API 호출 시 200 OK 응답과 함께 정상적인 JSON 데이터 수신 확인.

💡 요약 및 교훈

  • 환경 변수는 항상 최우선으로: API 설정 파일이나 서버 시작 파일 최상단에서 가장 먼저 로드되어야 한다.
  • 경로는 명시적으로: dotenv 사용 시 실행 환경(루트 vs 서브디렉토리)에 따라 파일 경로가 꼬일 수 있으므로 path.resolve를 쓰는 것이 안전하다.

+ Recent posts