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

이번 포스트에서는 파이썬 FastAPI 프레임워크와 JWT(JSON Web Tokens)를 활용하여 다중 계정 로그인과 권한 관리 시스템을 구현하는 방법에 대해 알아보겠습니다. 이 시스템은 사용자 인증과 권한 부여를 쉽게 관리하기 위해 보다 안전하고 효율적인 방법을 제공합니다.

FastAPI란 무엇인가요?

FastAPI는 파이썬의 강력한 웹 프레임워크 중 하나로, 빠른 속도와 현대적인 기능을 제공합니다. ASGI(Asynchronous Server Gateway Interface) 표준을 준수하며, 타입 힌트(type hinting) 기능을 사용하여 자동으로 API 스키마 및 문서를 생성할 수 있습니다. 또한 비동기적인 처리를 지원하므로 대량의 요청에 빠르게 응답할 수 있습니다.

JWT란 무엇인가요?

JWT(JSON Web Tokens)는 인증 정보를 안전하게 전달하기 위한 토큰 기반 인증 방식입니다. JWT는 JSON 형식으로 인코딩되어 사용자의 신원을 확인하고 권한을 부여하는 데 사용됩니다. 토큰의 구성은 헤더, 페이로드(Payload) 및 서명(Signature) 세 부분으로 나누어집니다.

다중 계정 로그인 시스템 구현 방법

  1. FastAPI 설치하기
    $ pip install fastapi
    $ pip install uvicorn
    
  2. JWT 라이브러리 설치하기
    $ pip install pyjwt
    
  3. FastAPI 애플리케이션 초기 설정하기
    from fastapi import FastAPI, Depends, HTTPException
    from fastapi.security import OAuth2PasswordBearer
    from jwt import PyJWTError, decode, encode
    from passlib.context import CryptContext
    from datetime import datetime, timedelta
    from typing import Optional
       
    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
       
    # 사용자 모델 정의하기
    class User:
        def __init__(self, username: str, password: str, scopes: list):
            self.username = username
            self.password = password
            self.scopes = scopes
       
    # 유효한 사용자인지 확인하기
    def verify_user(username: str, password: str):
        # 사용자 정보를 데이터베이스에서 조회하고 비밀번호를 확인하는 로직을 구현합니다.
        # 이 예제에서는 간단히 하기 위해 하드코딩으로 사용자 정보를 확인합니다.
        users = {
            "admin": User("admin", pwd_context.hash("admin"), ["admin"]),
            "user": User("user", pwd_context.hash("user"), ["read"])
        }
        if username in users and pwd_context.verify(password, users[username].password):
            return users[username]
       
    # 토큰 발급하기
    def create_access_token(data: dict, expires_delta: Optional[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 = encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
        return encoded_jwt
       
    # 토큰 인증하기
    async def get_current_user(token: str = Depends(oauth2_scheme)):
        try:
            payload = decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            username: str = payload.get("sub")
            if username is None:
                raise HTTPException(status_code=401, detail="Invalid authentication credentials")
            token_scopes = payload.get("scopes", [])
            token_data = {"username": username, "scopes": token_scopes}
        except PyJWTError:
            raise HTTPException(status_code=401, detail="Invalid authentication credentials")
        return token_data
       
    # 로그인 API 생성하기
    @app.post("/token")
    async def login(username: str, password: str):
        user = verify_user(username, password)
        if not user:
            raise HTTPException(status_code=401, detail="Incorrect username or password")
        access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            data={"sub": user.username, "scopes": user.scopes},
            expires_delta=access_token_expires
        )
        return {"access_token": access_token, "token_type": "bearer"}
       
    # 보호된 API 엔드포인트 생성하기
    @app.get("/protected")
    async def protected_route(user: dict = Depends(get_current_user)):
        if "admin" not in user["scopes"]:
            raise HTTPException(status_code=403, detail="Not enough permissions")
        return {"message": "You have admin access"}
    
  4. 애플리케이션 실행하기
    $ uvicorn main:app --reload
    

이제 FastAPI와 JWT를 활용한 다중 계정 로그인 및 권한 관리 시스템이 구현되었습니다. /token 엔드포인트로 로그인을 요청하면 인증된 사용자에게 액세스 토큰이 발급되며, /protected 엔드포인트는 admin 권한을 가진 사용자에게만 접근이 허용됩니다.

이 예제는 간단한 구현을 위한 것이며, 실제로는 데이터베이스와의 연동이 필요하고, 비밀번호 해싱 및 인증 정보의 보안 향상을 위한 추가 작업이 필요할 수 있습니다. 보다 복잡한 시스템에는 Flask 등의 다른 프레임워크를 고려해볼 수도 있습니다.

결론

파이썬 FastAPI와 JWT를 활용하여 다중 계정 로그인 및 권한 관리 시스템을 구현하는 방법에 대해 살펴보았습니다. FastAPI의 뛰어난 속도와 기능, 그리고 JWT를 통한 안전한 인증 방식을 활용하면 보다 효율적인 사용자 인증 및 권한 부여 시스템을 구축할 수 있습니다. 이를 활용하여 고도화된 웹 서비스를 개발해보세요.

#FastAPI #JWT