Authlib 공식 문서 - [FastAPI OAuth Client]

Soobin Kim·2024년 2월 27일

공부

목록 보기
13/15

목차

FastAPI OAuth 2.0 Client

  1. Create OAuth client
  2. Implement login route
  3. Handle authentication callback

FastAPI OAuth Client

  • FastAPI에서 세션을 사용하기 위해 middleware 등록
from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()

# 임시 코드 및 상태를 세션에 저장해야 합니다.
app.add_middleware(SessionMiddleware, secret_key="some-random-string")
  • app.add_middlewareSessionMiddleware을 등록하는 이유는 세션 관리를 위함이다. 세션 미들웨어는 요청과 응답 사이의 상태를 유지(클라이언트와 서버 간의 상태를 보존)하고 데이터를 저장하는데(클라이언트의 상태를 식별) 사용된다.
  • secret_key 인자는 세션 데이터 암호화를 위해 전달한다.
@app.get("/login/google")
async def login_via_google(request: Request):
    redirect_uri = request.url_for('auth_via_google')
    return await oauth.google.authorize_redirect(request, redirect_uri)

@app.get("/auth/google")
async def auth_via_google(request: Request):
    token = await oauth.google.authorize_access_token(request)
    user = token['userinfo']
    return dict(user)
  • login_via_google 라우트 함수는 /login/google 엔드포인트로 Google을 통해 로그인하기 위한 핸들러이며, auth_via_google 라우트 함수는 /auth/google 엔드포인트로 Google 인증을 처리하기 위한 핸들러다.
  • auth_via_google는 인증된 사용자의 정보를 포함한 딕셔너리를 반환한다.

1. Create OAuth client

  1. OAuth 클라이언트 생성
from authlib.integrations.starlette_client import OAuth
from starlette.config import Config

config = Config('.env')  # read config from .env file
oauth = OAuth(config)
oauth.register(
    name='google',
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
    client_kwargs={
        'scope': 'openid email profile'
    }
)
  • Google은 OpenID discovery 엔드포인트를 제공하기 때문에 access_token_urlauthorize_url 같은 추가 정보를 제공할 필요 없이 server_metadata_url만 전달하면 된다.

2. Implement login route

  • FastAPI 앱 생성
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="secret-string")
  • Authlib이 임시 코드와 상태를 저장하기 위해 request.session을 사용하므로 SessionMiddleware를 미들웨어로 등록해야 한다.

  • /login 엔드포인트는 Google의 접근 승인 엔드포인트로 리디렉션시킨다.

@app.route('/login')
async def login(request: Request):
    # absolute url for callback
    # we will define it below
    redirect_uri = request.url_for('auth')
    return await oauth.google.authorize_redirect(request, redirect_uri)
  • Google 웹사이트에서 액세스 권한을 부여하면 Google은 login 라우트 함수에서 정한 redirect_uri(request.url_for('auth'))인 auth 라우트로 다시 리디렉션된다.

3. Handle authentication callback

@app.route('/auth')
async def auth(request: Request):
    token = await oauth.google.authorize_access_token(request)
    # <=0.15
    # user = await oauth.google.parse_id_token(request, token)
    user = token['userinfo']
    return user
  • 성공적으로 권한을 부여받으면 access_tokenid_token을 포함하는 토큰을 얻는다.
  • id_token은 사용자 정보를 포함하며 디코딩 후 로그인 사용자의 정보를 얻을 수 있다 (via Discovery).

0개의 댓글