fastAPI + JWT 인증 1

2025. 4. 5. 00:23·Python

fastAPI 를 사용해서 JWT 인증을 구현하고자 합니다.

Windsurf 를 통해서 Claude 3.5 Sonnet 으로 자동생성한 파일을 소개합니다.

구글 로그인을 통해서 JWT 인증을 구현할 때 보안에 취약하지 않도록 해달라고 요청을 했습니다.

일단 ai 는 auth.py 라는 미들웨어 모듈을 생성해주었는데요

이 모듈은 JWT 토큰에 대한 검증을 수행하는 모듈입니다.

"""
JWT(JSON Web Token) 인증을 처리하는 미들웨어 모듈.
이 모듈은 FastAPI 애플리케이션에서 보호된 엔드포인트에 대한 접근을 제어합니다.
"""

from fastapi import Request, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from service.token_service import TokenService


class JWTBearer(HTTPBearer):
    """
    JWT 베어러 토큰 인증을 처리하는 커스텀 클래스.
    FastAPI의 HTTPBearer를 상속받아 JWT 특화 기능을 추가합니다.
    """
    
    def __init__(self, auto_error: bool = True):
        """
        JWTBearer 클래스 초기화
        
        Args:
            auto_error (bool): True일 경우 인증 실패 시 자동으로 에러를 발생시킴
        """
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        """
        각 요청에 대한 JWT 토큰 검증을 수행하는 메서드
        
        Args:
            request (Request): FastAPI의 요청 객체
            
        Returns:
            str: 유효한 JWT 토큰 문자열
            
        Raises:
            HTTPException: 인증 실패 시 403 Forbidden 에러 발생
        """
        # 상위 클래스의 __call__ 메서드를 호출하여 인증 정보 추출
        credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
        
        # 인증 정보가 없는 경우 에러 발생
        if not credentials:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Invalid authorization code"
            )
        
        # Bearer 토큰 방식이 아닌 경우 에러 발생    
        if credentials.scheme != "Bearer":
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Invalid authentication scheme"
            )
        
        try:
            # JWT 토큰 검증 및 페이로드 추출
            payload = TokenService.verify_token(credentials.credentials)
            # 요청 상태에 사용자 ID 저장 (후속 처리에서 사용 가능)
            request.state.user_id = int(payload.get("sub"))
        except Exception as e:
            # 토큰 검증 실패 시 에러 발생
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail=str(e)
            )
            
        return credentials.credentials

# 전역 JWT 베어러 인스턴스 생성
jwt_bearer = JWTBearer()

 

아래는 ai 를 통해 요청한 설명의 내용입니다.

auth.py 파일의 전체적인 구조와 동작을 설명하겠습니다:
1. 파일의 목적:
    - JWT(JSON Web Token) 기반의 인증을 처리하는 미들웨어를 구현합니다.
    - FastAPI 애플리케이션에서 보호된 엔드포인트에 대한 접근 제어를 담당합니다.
2. 주요 컴포넌트:JWTBearer 클래스:
    - FastAPI의 HTTPBearer를 상속받아 JWT 인증을 처리하는 커스텀 클래스
    - jwt_bearer 인스턴스: 애플리케이션 전역에서 사용할 수 있는 인증 핸들러 인스턴스
3. 인증 프로세스:
    - 클라이언트가 보호된 엔드포인트에 요청을 보낼 때 Authorization 헤더에 JWT 토큰을 포함시켜야 합니다.
    - call 메서드가 요청을 가로채서:
        * 인증 정보의 존재 여부 확인
        * Bearer 토큰 방식인지 확인
        * JWT 토큰의 유효성 검증
        * 토큰에서 사용자 ID 추출 및 요청 상태에 저장
4. 에러 처리:
    - 인증 정보 누락
    - 잘못된 인증 방식
    - 유효하지 않은 JWT 토큰 위의 경우들에 대해 403 Forbidden 응답을 반환합니다.

이 미들웨어는 보안이 필요한 엔드포인트에 쉽게 적용할 수 있으며, JWT 토큰 기반의 견고한 인증 시스템을 제공합니다.

 

 

이 방식에 따라 보호가 필요한 엔드포인트와 라우터마다 jwt_bearer 의존성을 추가하도록 합니다.

아래는 엔드포인트에 적용한 내용입니다.

@router.get("/", response_model=List[User], dependencies=[Depends(jwt_bearer)])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    return UserService.get_users(db=db, skip=skip, limit=limit)
    
    
@router.put("/{user_id}", response_model=User, dependencies=[Depends(jwt_bearer)])
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
    return UserService.update_user(db=db, user_id=user_id, user=user)

 

 

아래는 라우터에 적용한 것입니다.

router = APIRouter(
    prefix="/api/categories",
    tags=["categories"],
    responses={404: {"description": "Not found"}},
    dependencies=[Depends(jwt_bearer)]  # 모든 카테고리 엔드포인트에 JWT 인증 적용
)

 

 

이렇게 적용함으로 보호된 엔드포인트에 접근하려면 반드시 유효한 JWT 토큰이 필요하며, 토큰이 없거나 유효하지 않은 경우 403 Forbidden 에러가 발생합니다. 

클라이언트는 Authorization 헤더에 Bearer <token> 형식으로 토큰을 포함시켜야 합니다.

 

로그인 후 개발자도구를 통해서 로컬저장소를 확인하면 토큰이 들어가 있는 것을 확인할 수 있습니다.

저작자표시 (새창열림)

'Python' 카테고리의 다른 글

python 에서 화면 생성을 위해 사용중인 Jinja2Templates  (0) 2025.04.05
fastAPI + JWT 인증 2 - 토큰 생성 및 검증, 관리  (0) 2025.04.05
KOSIS 통계정보를 이용한 데이터 조회 방법  (0) 2025.03.29
python+fastAPI+postgresql 로 구성된 환경에서 간단한 CRUD 구현2  (0) 2025.03.28
python+fastAPI+postgresql 로 구성된 환경에서 간단한 CRUD 구현1  (0) 2025.03.28
'Python' 카테고리의 다른 글
  • python 에서 화면 생성을 위해 사용중인 Jinja2Templates
  • fastAPI + JWT 인증 2 - 토큰 생성 및 검증, 관리
  • KOSIS 통계정보를 이용한 데이터 조회 방법
  • python+fastAPI+postgresql 로 구성된 환경에서 간단한 CRUD 구현2
크레비즈
크레비즈
  • 크레비즈
    크레비즈 커뮤니티
    크레비즈
  • 전체
    오늘
    어제
    • 분류 전체보기 (68)
      • Front-end (13)
      • Back-end (7)
      • Python (11)
      • AI 공부 (7)
      • Mobile (4)
      • Script (4)
      • 인프라 (5)
      • 참고할 내용 (12)
      • reference page (0)
      • Project (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

    • Spring: the source for modern java
  • 공지사항

    • 크레비즈 커뮤니티
  • 인기 글

  • 태그

    vue
    Refresh Token
    ChatGPT
    Gemini
    windsurf
    CNN
    vuejs
    fastapi
    Claude
    Access Token
    claude 3.7 sonnet
    PYTHON
    딥러닝
    토큰
    claude sonnet
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
크레비즈
fastAPI + JWT 인증 1
상단으로

티스토리툴바