多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

FastAPI Users 8.x 到 9.x 迁移指南:Transport 与 Strategy 拆分重构认证后端

FastAPI Users 8.x 到 9.x 迁移指南:Transport 与 Strategy 拆分重构认证后端 后端认证鉴权Web框架【免费下载链接】fastapi-usersReady-to-use and customizable users management for FastAPI项目地址https://gitcode.com/gh_mirrors/fa/fastapi-users点击查看免费下载导读本文基于 FastAPI Users 官方迁移文档docs/migration/8x_to_9x.md系统讲解从 8.x 升级到 9.x 时认证体系的核心变化原先一个后端类同时负责令牌生成与传输的模型被拆分为Transport传输层与Strategy策略层两个独立概念并通过AuthenticationBackend组合。读完本文你将掌握如何将旧的JWTAuthentication/CookieAuthentication代码迁移为新式写法、如何为每个认证后端生成独立的 OAuth 路由以及迁移后的登录/登出底层调用链与 OpenAPI 响应差异。为什么 9.x 要拆分认证后端在 8.x 版本中一个认证后端如JWTAuthentication、CookieAuthentication同时承担两件事决定令牌如何生成与安全校验决定令牌如何随请求传输放在Authorization头还是写入 Cookie。9.x 将其拆成两个正交的抽象见 fastapi_users/authentication/transport/base.py 与 fastapi_users/authentication/strategy/base.pyTransport传输层令牌如何随请求携带对应BearerTransport、CookieTransportStrategy策略层令牌如何生成与校验对应JWTStrategy未来可扩展数据库会话令牌等新策略。拆分的直接收益正如迁移文档所言我们很快就能提供数据库会话令牌之类的新策略而无需重复编写完全相同的传输逻辑——传输逻辑与令牌生成逻辑从此可以独立演进、任意组合。迁移文档原文见 docs/migration/8x_to_9x.md。新架构三件套AuthenticationBackend Transport Strategy迁移后的核心组合类为AuthenticationBackend其定义位于 fastapi_users/authentication/backend.pyclass AuthenticationBackend(Generic[models.UP, models.ID]): def __init__( self, name: str, transport: Transport, get_strategy: DependencyCallable[Strategy[models.UP, models.ID]], ): self.name name self.transport transport self.get_strategy get_strategy三个参数含义对照 docs/configuration/authentication/backend.mdnamestr后端唯一名称9.x 起不再有默认值必须自行提供transport一个Transport实例负责令牌的携带方式get_strategy一个返回Strategy实例的依赖可调用对象Callable。之所以要求函数而非直接传实例是为了让策略能够随依赖动态实例化详见 docs/configuration/authentication/strategies/jwt.md 中的说明。AuthenticationBackend将两者编排成完整的认证流程backend.pyloginstrategy.write_token(user)生成令牌 →transport.get_login_response(token)返回携带令牌的 HTTP 响应logout调用strategy.destroy_token(token, user)尝试注销令牌若策略不支持销毁则静默跳过StrategyDestroyNotSupportedError随后调用transport.get_logout_response()若传输层不支持登出响应则返回204 No Content。从JWTAuthentication迁移迁移前8.xfrom fastapi_users.authentication import JWTAuthentication jwt_authentication JWTAuthentication( secretSECRET, lifetime_seconds3600, tokenUrlauth/jwt/login )迁移后9.xfrom fastapi_users.authentication import AuthenticationBackend, BearerTransport, JWTStrategy SECRET SECRET bearer_transport BearerTransport(tokenUrlauth/jwt/login) def get_jwt_strategy() - JWTStrategy: return JWTStrategy(secretSECRET, lifetime_seconds3600) auth_backend AuthenticationBackend( namejwt, transportbearer_transport, get_strategyget_jwt_strategy, )迁移要点tokenUrl从JWTAuthentication移交给BearerTransport构造参数bearer.py 中通过OAuth2PasswordBearer(tokenUrl, auto_errorFalse)构造 FastAPI 安全依赖secret、lifetime_seconds移交给JWTStrategy必须为后端提供name迁移文档中的红色警告docs/migration/8x_to_9x.md登录成功后BearerTransport返回200 OK的 JSON体为{access_token: ..., token_type: bearer}对应 BearerResponse。从CookieAuthentication迁移迁移前8.xfrom fastapi_users.authentication import CookieAuthentication cookie_authentication CookieAuthentication(secretSECRET, lifetime_seconds3600)迁移后9.xfrom fastapi_users.authentication import AuthenticationBackend, CookieTransport, JWTStrategy SECRET SECRET cookie_transport CookieTransport(cookie_max_age3600) def get_jwt_strategy() - JWTStrategy: return JWTStrategy(secretSECRET, lifetime_seconds3600) auth_backend AuthenticationBackend( namecookie, transportcookie_transport, get_strategyget_jwt_strategy, )迁移要点旧代码里lifetime_seconds3600同时控制令牌有效期与 Cookie 存活期迁移后两者被拆分——令牌有效期由JWTStrategy(lifetime_seconds3600)控制Cookie 存活期由CookieTransport(cookie_max_age3600)控制cookie.pyCookieTransport支持更细粒度的 Cookie 参数cookie_name默认fastapiusersauth、cookie_path默认/、cookie_domain、cookie_secure默认True、cookie_httponly默认True、cookie_samesitelax/strict/none默认lax。登录时通过response.set_cookie(...)写入令牌登出时以空值与max_age0清除cookie.py与 Bearer 不同Cookie 登录/登出响应均为204 No ContentOpenAPI 文档中同样以204建模cookie.py。迁移文档特别强调两个示例中的get_jwt_strategy完全一致——这正是令牌生成与传输解耦的直观体现同一套 JWT 策略可以既用于 Bearer 头也用于 Cookie。登录响应差异速查传输层登录成功响应登出响应令牌携带方式BearerTransport200 OKJSON{access_token: ..., token_type: bearer}204 No Content由后端兜底返回Authorization: Bearer tokenCookieTransport204 No ContentSet-Cookie204 No Content 清除 CookieCookie: fastapiusersauthtoken依据BearerTransport.get_logout_response()会抛出TransportLogoutNotSupportedErrorbearer.py此时AuthenticationBackend.logout会捕获该异常并返回204backend.py该行为由 tests/test_authentication_backend.py 中的test_logout用例验证。多个后端与JWTStrategy细节一个应用多个认证后端新架构允许你自由组合既可以用多个 transport 搭配同一个JWTStrategy也可以为不同后端提供不同策略例如日后引入的数据库会话令牌。只需为每个组合生成一个AuthenticationBackend再逐一传入FastAPIUsers实例并为其生成认证路由。更完整的参数说明可参考 docs/configuration/authentication/backend.md 与 docs/configuration/authentication/strategies/jwt.md。JWTStrategy构造参数从源码strategy/jwt.py与 jwt 策略文档 可以看到secret签名密钥务必使用强口令并妥善保管lifetime_secondsOptional[int]令牌有效秒数设为None则永不过期存在严重安全隐患token_audienceOptional[list[str]]JWT 合法受众默认[fastapi-users:auth]algorithmOptional[str]JWT 加密算法默认HS256需要非对称密钥时改用RS256public_key使用 RSA 等非对称算法时提供解密公钥secret始终用于加密。write_token将用户 ID 写入sub声明并生成令牌read_token校验签名与受众后通过user_manager.parse_iduser_manager.get还原用户strategy/jwt.py。由于 JWT 天然无状态登出即失效无法实现destroy_token会抛出JWTStrategyDestroyNotSupportedError交由后端静默忽略strategy/jwt.py这也是 jwt 策略文档 中Logout 什么都不做的源码依据。OAuth一个后端一个路由迁移前8.x8.x 中单个 OAuth 路由即可配合任意一个认证后端工作app.include_router( fastapi_users.get_oauth_router(google_oauth_client, SECRET), prefix/auth/google, tags[auth], )迁移后9.x现在必须为每个认证后端生成独立的 OAuth 路由将auth_backend作为第二个位置参数传入app.include_router( fastapi_users.get_oauth_router(google_oauth_client, auth_backend, SECRET), prefix/auth/google, tags[auth], )迁移文档明确指出现在你需要为你的每一个后端分别生成一个路由。 如果你有多个 OAuth 客户端和/或多个认证后端就需为每一对组合创建路由同 docs/configuration/oauth.md 的说明。从源码看router/oauth.pyget_oauth_router在 9.x 中的签名确实加入了backend: AuthenticationBackend参数且回调路由名变为oauth:{client.name}.{backend.name}.callback——不同后端对应的 callback 路由由此天然区分。OAuth 回调端点通过Depends(backend.get_strategy)注入策略并以backend.login(strategy, user)完成最终登录router/oauth.py。/authorize不再需要authentication_backend参数迁移的一个直接结果是请求/authorize时不再需要指定authentication_backend查询参数。迁移前curl \ -H Content-Type: application/json \ -X GET \ http://localhost:8000/auth/google/authorize?authentication_backendjwt迁移后curl \ -H Content-Type: application/json \ -X GET \ http://localhost:8000/auth/google/authorize原因很自然既然每个 OAuth 路由现在已与唯一的AuthenticationBackend绑定在生成路由时指定用哪个后端登录就不必再由客户端在请求时声明。/authorize端点仅返回授权跳转 URLOAuth2AuthorizeResponse.authorization_url真正与后端交互发生在/callbackrouter/oauth.py。迁移检查清单删除JWTAuthentication/CookieAuthentication的实例化代码分别实例化BearerTransport(tokenUrl...)或CookieTransport(cookie_max_age...)定义get_jwt_strategy()返回JWTStrategy(secret..., lifetime_seconds...)用AuthenticationBackend(name..., transport..., get_strategy...)组合三者务必提供唯一name将后端列表传入FastAPIUsers实例并为其逐一生成 auth 路由OAuth 路由改为get_oauth_router(client, auth_backend, SECRET)每后端一个移除请求/authorize时携带的authentication_backend参数。迁移后到哪里看完整示例迁移文档在结尾提示如果你不确定或有些迷茫务必查看完整可运行示例docs/migration/8x_to_9x.md。仓库中提供了可直接对照的完整工程认证与传输配置总览docs/configuration/full-example.mdSQLAlchemy Bearer/JWT 示例examples/sqlalchemy/app/app.py、examples/sqlalchemy/app/users.pyBeanie Bearer/JWT 示例examples/beanie/app/app.py、examples/beanie/app/users.pySQLAlchemy OAuth 示例examples/sqlalchemy-oauth/app/app.pyBeanie OAuth 示例examples/beanie-oauth/app/app.py这些示例均已在 9.x 新架构下编写迁移时可直接对照其中的AuthenticationBackend组装方式与 OAuth 路由注册方式。赞分享后端认证鉴权Web框架【免费下载链接】fastapi-usersReady-to-use and customizable users management for FastAPI项目地址https://gitcode.com/gh_mirrors/fa/fastapi-users点击查看免费下载相关推荐FastAPI-Users 从 8.x 到 9.x 版本迁移指南认证架构的重大革新FastAPI Users 从 8.x 到 9.x 版本迁移指南认证架构的重大革新 前言 FastAPI Users 作为 FastAPI 生态中优秀的用户认后端认证鉴权Web框架深入解析 FastAPI Users 认证后端用 AuthenticationBackend 组合 Transport 与 Strategy深入解析 FastAPI Users 认证后端用 AuthenticationBackend 组合 Transport 与 Strategy 本文围绕 Fas后端认证鉴权Web框架FastAPI Users 认证体系完全指南Transport Strategy 组合式认证后端详解FastAPI Users 认证体系完全指南Transport Strategy 组合式认证后端详解 导读 本文是 FastAPI Users 认证体系的后端认证鉴权Web框架上一篇如何在Blender中实现精准2D草图绘制CAD Sketcher约束建模终极指南下一篇终极指南如何免费解锁WeMod专业版功能 - 使用开源WandEnhancer工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表