from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
# 임시 코드 및 상태를 세션에 저장해야 합니다.
app.add_middleware(SessionMiddleware, secret_key="some-random-string")
app.add_middleware에 SessionMiddleware을 등록하는 이유는 세션 관리를 위함이다. 세션 미들웨어는 요청과 응답 사이의 상태를 유지(클라이언트와 서버 간의 상태를 보존)하고 데이터를 저장하는데(클라이언트의 상태를 식별) 사용된다.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
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'
}
)
access_token_url와 authorize_url 같은 추가 정보를 제공할 필요 없이 server_metadata_url만 전달하면 된다.2. Implement login route
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)
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_token과 id_token을 포함하는 토큰을 얻는다.id_token은 사용자 정보를 포함하며 디코딩 후 로그인 사용자의 정보를 얻을 수 있다 (via Discovery).