6.3 FastAPI에서 JWT 인증 구현

약 7분

본문 듣기
읽기 설정

글자 크기

줄 간격

글꼴

6.3 FastAPI에서 JWT 인증 구현

이번 섹션에서는 FastAPI를 사용하여 JWT(JSON Web Token)를 기반으로 인증 시스템을 구현해 보겠습니다. JWT는 사용자의 정보를 안전하게 전달할 수 있는 방식으로, 주로 인증 및 정보 교환에 사용됩니다. 실습 프로젝트를 통해 이론을 적용해 보겠습니다.

요구 사항

  • Python 3.13
  • FastAPI 설치: pip install fastapi uvicorn
  • PyJWT 설치: pip install pyjwt
  • SQLAlchemy 설치: pip install sqlalchemy databases

프로젝트 구조

  • main.py: FastAPI 애플리케이션
  • models.py: 데이터베이스 모델
  • auth.py: 인증 관련 기능
  • database.py: 데이터베이스 연결 설정

이제 각 파일의 내용에 대해 살펴보겠습니다.

코드 python
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordCredentials
from pydantic import BaseModel
import jwt
import datetime

app = FastAPI()

# OAuth2 설정
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")

# 사용자 모델 정의
class User(BaseModel):
    username: str
    email: str = None
    full_name: str = None

class UserInDB(User):
    hashed_password: str

# 가짜 사용자 데이터
fake_users_db = {
    "johndoe": UserInDB(
        username="johndoe",
        email="johndoe@example.com",
        full_name="John Doe",
        hashed_password=
            "$2b$12$KIXP33JFEBJplA8c54HCgObD5zrlY5DQd4z8XIxw0.nj2bb.BpKNG"
    )
}

# 비밀번호 확인 함수
def verify_password(plain_password, hashed_password):
    return plain_password == hashed_password # 실제로는 해시 비교를 해야 함.

# 사용자 인증 함수
def get_user(db, username: str):
    if username in db:
        return db[username]
    return None

# JWT 생성 함수
def create_jwt_token(data: dict):
    token = jwt.encode({"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1), **data}, "SECRET_KEY", algorithm="HS256")
    return token

# 로그인 엔드포인트
@app.post("/token")
async def login(form_data: OAuth2PasswordCredentials = Depends(oauth2_scheme)):
    user = get_user(fake_users_db, form_data.username)
    if not user or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    token = create_jwt_token(data={'sub': user.username})
    return {"access_token": token, "token_type": "bearer"}

# 보호된 엔드포인트
@app.get("/users/me", response_model=User)
async def read_users_me(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(status_code=401, detail="Could not validate credentials")
    try:
        payload = jwt.decode(token, "SECRET_KEY", algorithms=["HS256"])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except jwt.PyJWTError:
        raise credentials_exception
    user = get_user(fake_users_db, username=username)
    if user is None:
        raise credentials_exception
    return user

댓글 0

댓글을 남기려면 로그인하세요.

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.