You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI结合Authlib外部OAuth认证:正确复用客户端的疑问

改进Authlib与FastAPI的协作实现

核心优化点

  • 移除手动存储/读取access_token的冗余代码
  • 利用Authlib内置的令牌管理机制实现自动刷新
  • 通过官方推荐的客户端调用方式简化外部API请求

修改后的完整代码

from authlib.integrations.base_client import OAuthError
from authlib.integrations.starlette_client import OAuth
from fastapi import FastAPI, HTTPException
from starlette.requests import Request
from starlette.responses import HTMLResponse, RedirectResponse
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="some-random-string")
oauth = OAuth()
oauth.register(
    name="oauthprovider",
    client_id="MYCLIENTID",
    client_secret="MYCLIENTSECRET",
    server_metadata_url="https://example.com/.well-known/openid-configuration",
    # 显式开启自动刷新(默认已启用,声明后更清晰)
    auto_refresh_url=None,
    refresh_token_url=None,
)

@app.get('/login')
async def login(request: Request):
    redirect_uri = "http://localhost:8000/auth/callback"
    return await oauth.oauthprovider.authorize_redirect(request, redirect_uri)

@app.get('/auth/callback')
async def auth(request: Request):
    try:
        # Authlib会自动将完整令牌对象存入session,无需手动处理
        token = await oauth.oauthprovider.authorize_access_token(request)
    except OAuthError as error:
        return HTMLResponse(f'<h1>{error.error}</h1>')
    user = token.get('userinfo')
    if user:
        request.session['user'] = dict(user)
    # 移除手动存储access_token的代码
    return RedirectResponse(url='/docs')

@app.get('/fetchexternalAPI')
async def externalAPI(request: Request):
    try:
        # 使用Authlib客户端的异步方法,自动处理令牌获取与刷新
        response = await oauth.oauthprovider.get(
            "https://example.com/api",
            request=request
        )
        response.raise_for_status()
        return response.json()
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

关键细节说明

  1. 令牌自动存储:authorize_access_token方法会把包含access_token、refresh_token、过期时间的完整令牌对象,自动序列化存入session的_oauth_oauthprovider_token键下(命名规则为_oauth_<provider_name>_token)。
  2. 自动刷新逻辑:调用客户端的get/post等方法时,Authlib会自动检查令牌是否过期。如果过期且存在有效refresh_token,会自动向授权服务器请求刷新令牌,并更新session中的令牌数据,全程无需手动干预。
  3. 异步架构适配:使用Authlib提供的异步HTTP方法,与FastAPI的异步模型匹配,避免阻塞事件循环。

额外注意事项

  • 确保授权服务器返回的令牌包含refresh_token和expires_in字段,否则自动刷新无法生效。
  • 生产环境中,SessionMiddleware的secret_key必须使用安全的随机字符串,禁止硬编码。

内容的提问来源于stack exchange,提问作者tenup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:21:02