Loading...
Loading...
02-reusable-code-python/api/fastapi_auth.py
"""
FastAPI API Key 인증 미들웨어 - 선택적 API Key 기반 인증
@source voice-to-text-v2
@extracted 2026-02-15
@version 1.0.0
의존성:
- fastapi
사용법:
from api.fastapi_auth import create_api_key_dependency
# 기본 (환경변수: API_KEY)
verify_api_key = create_api_key_dependency()
# 커스텀 환경변수명
verify_api_key = create_api_key_dependency(env_var="MY_SERVICE_API_KEY")
# 라우터에 적용
router = APIRouter(dependencies=[Depends(verify_api_key)])
# 또는 개별 엔드포인트에 적용
@app.get("/protected", dependencies=[Depends(verify_api_key)])
async def protected_endpoint():
return {"message": "authenticated"}
환경변수 미설정 시:
모든 요청 허용 (로컬 개발 모드)
"""
import os
import logging
from typing import Callable
from fastapi import HTTPException, Security
from fastapi.security import APIKeyHeader
logger = logging.getLogger(__name__)
def create_api_key_dependency(
env_var: str = "API_KEY",
header_name: str = "X-API-Key",
) -> Callable:
"""
선택적 API Key 인증 의존성 팩토리.
환경변수가 설정되어 있으면 해당 키로 인증 활성화.
미설정 시 모든 요청을 허용 (개발 모드).
Args:
env_var: API Key를 저장한 환경변수 이름 (기본: "API_KEY")
header_name: 요청 헤더 이름 (기본: "X-API-Key")
Returns:
FastAPI 의존성 함수
사용 예시:
# 환경변수 설정으로 인증 활성화
export API_KEY=your-secret-key
# 요청 시 헤더에 포함
curl -H "X-API-Key: your-secret-key" http://localhost:8000/api/endpoint
"""
api_key_header = APIKeyHeader(name=header_name, auto_error=False)
api_key_value = os.environ.get(env_var, "")
if api_key_value:
logger.info(f"API Key 인증 활성화 (env: {env_var}, header: {header_name})")
else:
logger.info(f"API Key 미설정 ({env_var}) - 모든 요청 허용 (개발 모드)")
async def verify_api_key(
api_key: str | None = Security(api_key_header),
) -> str | None:
"""API Key 검증"""
if not api_key_value:
# API Key 미설정 → 모든 요청 허용
return None
if not api_key:
raise HTTPException(
status_code=401,
detail=f"API Key 필요. {header_name} 헤더를 설정하세요.",
)
if api_key != api_key_value:
raise HTTPException(
status_code=403,
detail="유효하지 않은 API Key.",
)
return api_key
return verify_api_key