[python] FastAPI에서 로그인 구현하기

FastAPI는 빠르고 강력한 웹 프레임워크로, 사용자 인증 및 인가 기능을 간단하게 구현할 수 있습니다. 이번에는 FastAPI를 사용하여 로그인 기능을 구현하는 방법에 대해 알아보겠습니다.

패키지 설치

먼저 FastAPI와 필요한 패키지를 설치해야 합니다. 아래의 명령어를 사용하여 필요한 패키지를 설치해주세요.

pip install fastapi
pip install uvicorn[standard]
pip install passlib

모델 생성

데이터베이스에 유저 정보를 저장하기 위해 User 모델을 생성합니다. 아래의 코드를 사용하여 models.py 파일에 모델을 작성해주세요.

from pydantic import BaseModel

class User(BaseModel):
    username: str
    password: str

로그인 라우터

이제 로그인 기능을 처리하는 라우터를 구현해보겠습니다. 아래의 코드를 사용하여 main.py 파일에 라우터를 작성해주세요.

from fastapi import FastAPI
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from passlib.context import CryptContext
from datetime import datetime, timedelta
from jose import JWTError, jwt

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # 인증 정보 검증 작업
    user = get_user(form_data.username)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    if not verify_password(form_data.password, user.password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

@app.get("/protected")
async def protected_route(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        if username is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid authentication credentials",
                headers={"WWW-Authenticate": "Bearer"},
            )
        return {"message": "You have access to the protected route"}
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

서버 띄우기

마지막으로, 아래의 명령어를 사용하여 서버를 띄워보세요.

uvicorn main:app --reload

이제 http://localhost:8000/docs에 접속하여 Swagger UI를 통해 로그인 API를 사용해볼 수 있습니다.

결론

FastAPI를 사용하여 로그인 기능을 구현하는 방법에 대해 알아보았습니다. 이 기법을 활용하여 사용자 인증이 필요한 웹 애플리케이션을 개발하면 보안성을 높일 수 있습니다. FastAPI의 강력한 기능을 활용하여 빠르고 안정적인 웹 애플리케이션을 개발해보세요.