파이썬 FastAPI와 JWT를 활용한 다중 계정 로그인 및 권한 관리 시스템 구현 방법

FastAPI

이번 블로그 포스트에서는 파이썬 FastAPI 프레임워크와 JWT(JSON Web Token)를 활용하여 다중 계정 로그인 및 권한 관리 시스템을 어떻게 구현하는지 알아보겠습니다. FastAPI는 빠르고 현대적인 웹 프레임워크이며, JWT는 사용자 인증과 권한 부여를 단순하고 안전하게 구현하는 데 사용됩니다.

1. 프로젝트 설정

먼저, FastAPI와 JWT를 사용하기 위해 파이썬 가상환경을 설정하고 필요한 패키지들을 설치합니다. 다음 명령어를 사용하여 FastAPI, JWT 및 관련 패키지를 설치할 수 있습니다.

pip install fastapi uvicorn python-jose[pyopenssl] passlib[bcrypt] python-multipart

2. 사용자 모델 및 CRUD 작업

데이터베이스에 사용자 정보를 저장하고 관리하기 위해 사용자 모델 및 CRUD(Create, Read, Update, Delete) 작업을 설정합니다. 다음은 User 모델 클래스의 예시입니다.

class User(BaseModel):
    id: int
    username: str
    password: str
    role: str

CRUD 작업은 Create, Read, Update, Delete의 약자이며, 데이터베이스와 상호작용하여 사용자 정보를 생성, 조회, 수정, 삭제하는 작업을 말합니다. 이를 위해 SQLAlchemy 라이브러리와 함께 CRUD 작업을 구현합니다.

3. 사용자 인증과 JWT 발급

사용자 인증은 사용자가 입력한 로그인 정보가 올바른지 확인하는 과정입니다. 인증에 성공한 경우, JWT를 발급하여 사용자에게 리턴합니다. FastAPI는 JWT 토큰 생성과 인증을 쉽게 처리할 수 있는 PyJWT 라이브러리를 내장하고 있습니다.

from jose import jwt
from passlib.context import CryptContext

SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def create_access_token(user_id: int):
    data = {"sub": str(user_id)}
    expires_delta = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    return jwt.encode(
        data,
        SECRET_KEY,
        algorithm=ALGORITHM,
        expires_delta=expires_delta
    )

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

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

4. 로그인 및 인증 엔드포인트 생성

이제 로그인 및 인증을 처리하는 엔드포인트를 생성합니다. 아래 예시는 FastAPI에서 /login 엔드포인트로 POST 요청이 들어오면, 사용자 정보를 확인하고 JWT를 발급하는 예시입니다.

from fastapi import FastAPI, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")

@app.post("/login")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user = get_user_by_username(form_data.username)
    if not user:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    if not verify_password(form_data.password, user.password):
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    access_token = create_access_token(user.id)
    return {"access_token": access_token, "token_type": "bearer"}

5. JWT 인증 데코레이터 작성

JWT 토큰이 유효한지 검증하기 위해 데코레이터를 작성합니다. 아래 예시는 FastAPI에서 @app.get("/users") 엔드포인트에 JWT 인증을 적용하는 예시입니다.

from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")

def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: int = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=401, detail="Invalid authentication credentials")
        return get_user_by_id(user_id)
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid authentication credentials")

@app.get("/users", dependencies=[Depends(get_current_user)])
def get_users():
    ...

6. 권한 관리

권한 관리를 위해 사용자의 역할(role)을 확인하여 특정 작업에 대한 권한을 부여합니다. 예를 들어, 특정 엔드포인트에 접근하려면 “admin” 역할을 가진 사용자만 접근할 수 있도록 설정할 수 있습니다.

def get_current_user(token: str = Depends(oauth2_scheme)):
    ...
    if user.role != "admin":
        raise HTTPException(status_code=403, detail="Insufficient privileges")
    return user

결론

이상으로 FastAPI와 JWT를 활용하여 다중 계정 로그인 및 권한 관리 시스템을 구현하는 방법에 대해 알아보았습니다. FastAPI의 빠른 속도와 강력한 기능을 통해 사용자 인증 및 권한 관리 시스템을 간편하게 구축할 수 있습니다. FastAPI와 JWT를 활용하여 안전하고 효율적인 웹 서비스를 개발해보세요!

#python #FastAPI #JWT #로그인 #권한관리