[FastAPI] 🔐 JWT 로그인 구현하기

2025. 8. 7. 18:58·Python Framework/FastAPI

목차


     

    사용자 인증은 모든 웹 서비스의 핵심이다.
    FastAPI에서는 JWT (JSON Web Token)를 활용하여 인증 기능을 간결하면서도 강력하게 구현할 수 있다.

     

    이 글에서는 JWT 토큰 생성 → 검증 → 로그인 구현까지 실전 예제로 설명한다. 또한 FastAPI의 HTTPException과 status를 활용한 예외 처리도 함께 다룬다.

    JWT란?

    JWT (Json Web Token)는 클라이언트와 서버 간에 서로 신뢰할 수 있는 방식으로 정보를 주고받기 위한 토큰 포맷이다.

    JWT는 다음과 같은 구조를 가진다.

     

    Header.Payload.Signature

     

    예시 payload:

    {
      "id": 123,
      "exp": 1723042151
    }

     

    준비 사항

    JWT 처리를 위해 python-jose 라이브러리를 사용한다. 설치는 아래와 같다.

    pip install "python-jose[cryptography]" fastapi

     

    비밀번호 비교를 위해 passlib도 함께 사용하는 것을 권장한다.

    pip install passlib[bcrypt]
     

    JWT 토큰 생성 함수

    from datetime import datetime, timedelta, timezone
    from jose import jwt
    
    SECRET_KEY = "THIS_IS_SUPER_SECRET_KEY"
    ALGORITHM = "HS256"
    
    def create_access_token(payload: dict, expires_delta: timedelta = timedelta(hours=6)) -> str:
        expire = datetime.now(timezone.utc) + expires_delta
        payload.update({"exp": expire})
        return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

     

    • payload: 토큰에 담을 사용자 정보 (user_id, 권한 등)
    • exp: 토큰 만료 시간 (UTC 기준)
    • jwt.encode: 서명된 JWT 토큰을 생성한다

     

    JWT 토큰 검증 함수

    from fastapi import HTTPException, status
    from jose import JWTError, jwt
    
    def decode_access_token(token: str) -> dict:
        try:
            return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        except JWTError:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token")

     

    • jwt.decode: JWT를 복호화한다
    • 실패 시 JWTError가 발생하며, HTTP 401 에러로 처리한다

    로그인 함수 구현

    다음은 실제 로그인 로직이다.
    사용자가 이메일과 비밀번호로 로그인하면 아래 절차를 따른다.

    1. 이메일로 사용자 조회
    2. 비밀번호 검증
    3. JWT 토큰 발급
    from fastapi import HTTPException, status
    
    class AuthService:
        def __init__(self, user_repo, crypt):
            self.user_repo = user_repo  # 사용자 조회를 위한 repository
            self.crypt = crypt          # 암호화 비교 유틸 (예: passlib)
    
        def login(self, email: str, password: str) -> str:
            user = self.user_repo.find_by_email(email)
    
            if user is None:
                raise HTTPException(status.HTTP_404_NOT_FOUND, detail="User not found")
    
            if not self.crypt.verify(password, user.password):
                raise HTTPException(status.HTTP_401_UNAUTHORIZED, detail="Incorrect password")
    
            return create_access_token(payload={"id": user.id})

     

    • 반환 결과
    {
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMDFLMjFYSFJBOTNaUVJSS1BaQlJQRzFZRVgiLCJleHAiOjE3NTQ1ODAzMDV9.0NqjJBlT4MT4DDAn-xGfm4dF8ZFyFsoFTukSNZHDzus",
      "token_type": "bearer"
    }

    공식 문서 참고

    • FastAPI - JWT 보안 가이드
      https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/
    • python-jose GitHub
      https://github.com/mpdavis/python-jose
    • passlib (비밀번호 해시 라이브러리)
      https://passlib.readthedocs.io/

     

    마무리 요약

    토큰 생성 create_access_token() 함수 사용
    토큰 검증 decode_access_token() 함수 사용
    로그인 구현 이메일 조회 및 비밀번호 검증
    예외 처리 HTTPException과 status 활용
     

    FastAPI에서 JWT 인증을 직접 구현하면 비교적 단순하면서도 유연하게 확장할 수 있다.

    'Python Framework > FastAPI' 카테고리의 다른 글

    [FastAPI] 📌 BackgroundTasks vs Celery — 언제 뭐 쓰면 좋을까?  (5) 2025.08.15
    [FastAPI] 🔭 OAuth2 Scopes  (6) 2025.08.10
    'Python Framework/FastAPI' 카테고리의 다른 글
    • [FastAPI] 📌 BackgroundTasks vs Celery — 언제 뭐 쓰면 좋을까?
    • [FastAPI] 🔭 OAuth2 Scopes
    Log Cat
    Log Cat
    잊어버리지 않기 위한 메모장
    • Log Cat
      개발 메모장
      Log Cat
    • 전체
      오늘
      어제
      • 전체보기 (45) N
        • Book Review (6)
        • Language (15) N
          • Java (10) N
          • Go (1)
          • JavaScript (1)
          • TypeScript (3)
        • Computer Science (3)
          • Network (1)
          • Database (1)
          • Design Pattern (0)
        • Spring Framework (10)
          • Spring & Spring Boot (4)
          • Spring Batch (4)
          • Servlet & JSP (2)
        • Python Framework (3)
          • FastAPI (3)
        • Infra (3)
          • Dcoker (1)
          • Kafka (2)
        • ORM (1)
          • JPA (1)
        • Fun (1) N
        • Error (2)
        • Retrospective (0)
        • Certificate (1)
    • 블로그 메뉴

      • 홈
      • 태그
      • 방명록
    • 링크

      • Github
    • 인기 글

    • 태그

      Python
      백준
      자바
      jvm
      성공과 실패를 결정하는 1%의 네트워크 원리
      프로그래머스문제
      fastapi
      effective java 3/e
      코딩테스트
      자바 풀이
      개발서적
      프로그래머스 문제
      리트코드
      BOJ
      programmers
      spring
      네트워크 원리
      이팩티브 자바
      leetcode
      spring kafka
      코테
      우아한테크코스
      프로그래머스
      개발서적리뷰
      네트워크
      jmm
      escape-analysis
      Java
      spring boot
      Typescript
    • 최근 글

    • hELLO· Designed By정상우.v4.10.6
    Log Cat
    [FastAPI] 🔐 JWT 로그인 구현하기
    상단으로

    티스토리툴바