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

FastAPI는 강력한 웹 프레임워크로, 소셜 로그인 기능을 쉽게 구현할 수 있습니다. 소셜 로그인은 사용자가 다른 웹 서비스의 계정으로 로그인할 수 있게 하는 기능으로, 사용자 인증을 간편하게 처리할 수 있습니다.

이번 예제에서는 FastAPI와 OAuth2를 사용하여 소셜 로그인을 구현하는 방법을 살펴보겠습니다.

1. FastAPI 및 필수 패키지 설치

먼저, FastAPI를 설치해야 합니다. 다음 명령어를 실행하여 FastAPI와 OAuth 관련 패키지를 설치합니다.

pip install fastapi[all]

2. 소셜 로그인 설정

소셜 로그인을 위해 각 서비스에서 발급된 클라이언트 ID와 비밀 키가 필요합니다. 이 예제에서는 Google 로그인을 사용합니다. 따라서 Google 개발자 콘솔에서 프로젝트를 생성하고, OAuth 클라이언트 ID를 생성해야 합니다.

Google 개발자 콘솔에서 생성한 클라이언트 ID와 비밀 키를 각각 GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET에 저장합니다.

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2AuthorizationCodeBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from pydantic import BaseModel
from starlette.config import Config
from starlette.requests import Request
from starlette.responses import RedirectResponse

app = FastAPI()

async def get_current_user(token: str = Depends(oauth2_scheme)):
    """
    현재 사용자 정보를 반환합니다.
    """
    credentials_exception = HTTPException(
        status_code=401,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        token_data = TokenData(username=username)
    except JWTError:
        raise credentials_exception
    user = await get_user(username=token_data.username)
    if user is None:
        raise credentials_exception
    return UserInDB(**user)

@app.get("/login")
async def login(request: Request):
    """
    Google 로그인 페이지로 이동합니다.
    """
    google_oauth_url = f"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={GOOGLE_CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=email"
    return RedirectResponse(url=google_oauth_url)

3. 로그인 콜백 처리

소셜 로그인 시, 서비스 측에서 사용자가 로그인에 성공한 후에 콜백 URL로 리디렉션을 전송합니다. 이때, 액세스 토큰을 받아와서 사용자 정보를 가져올 수 있습니다.

@app.get("/login/callback")
async def login_callback(request: Request, code: str):
    """
    Google 로그인 콜백 처리
    """
    token_data = await get_access_token(code)
    user_info = await get_user_info(token_data.access_token)
    # 사용자 정보를 바탕으로 로그인 처리를 진행
    user = process_login(user_info)
    # 로그인 성공 후 리디렉션
    response = RedirectResponse("https://example.com/success")
    return response

4. 사용자 정보 가져오기

액세스 토큰을 사용하여 소셜 로그인 서비스로부터 사용자 정보를 가져옵니다. 이 예제에서는 Google API를 사용하여 사용자 정보를 가져오는 함수로 get_user_info를 사용합니다.

import requests

async def get_user_info(access_token: str):
    """
    사용자 정보 조회
    """
    headers = {"Authorization": f"Bearer {access_token}"}
    response = requests.get("https://www.googleapis.com/oauth2/v2/userinfo", headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        raise HTTPException(status_code=400, detail="Failed to retrieve user information")

결론

FastAPI를 사용하여 소셜 로그인을 구현하는 방법을 살펴보았습니다. FastAPI는 강력한 기능을 제공하며, OAuth2와의 연동을 통해 소셜 로그인을 쉽게 구현할 수 있습니다. 소셜 로그인은 사용자 인증을 간단하게 처리할 수 있는 방법이므로, 웹 서비스 개발 시 유용하게 활용할 수 있습니다.

이 예제에서는 Google 로그인을 기준으로 설명하였지만, 다른 소셜 로그인 서비스에도 적용할 수 있습니다. OAuth2 스펙에 맞게 각 서비스별로 설정을 변경하면 다른 소셜 로그인 서비스와도 연동할 수 있습니다.

FastAPI 공식 문서 및 OAuth2 관련 문서를 참고하여 자세한 내용을 확인해보세요.

참고 자료