惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
F
Full Disclosure
A
About on SuperTechFans
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
Know Your Adversary
Know Your Adversary
K
Kaspersky official blog
L
LINUX DO - 热门话题
Recorded Future
Recorded Future
C
Cisco Blogs
M
MIT News - Artificial intelligence
T
Tenable Blog
G
GRAHAM CLULEY
月光博客
月光博客
Recent Announcements
Recent Announcements
V
Visual Studio Blog
IT之家
IT之家
T
The Exploit Database - CXSecurity.com
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
P
Privacy International News Feed
P
Proofpoint News Feed
I
Intezer
博客园 - 叶小钗
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - Franky
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
小众软件
小众软件
Hacker News - Newest:
Hacker News - Newest: "LLM"
O
OpenAI News
N
News and Events Feed by Topic
Microsoft Security Blog
Microsoft Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic
The Cloudflare Blog
Spread Privacy
Spread Privacy
酷 壳 – CoolShell
酷 壳 – CoolShell
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
B
Blog RSS Feed

博客园 - 一名程序媛呀

Anki插件开发必知必会:钩子函数与右键菜单定制 httpx 传参总报错?这次把 GET、POST、文件上传到响应处理的坑给你一次填平 从卡顿到丝滑:FastAPI 调用外部 API 的正确姿势(httpx 实战) 还在 XHR、Fetch 和 Axios 之间纠结?我踩过的坑,希望你一个都不用碰到 你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南 Uvicorn、Gunicorn 傻傻分不清?FastAPI 生产部署避坑指南 Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招! 刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API 别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了 掏出手机就能搭个 WebDAV 同步服务器?这操作有点香 别只盯着GitBook了!这个文档神器让你的笔记秒变网站 写爬虫时用了代理还被封?Python 代理的那些隐藏坑,我替你踩明白了 旧手机别扔!用 Termux 搭个私人云盘,比网盘香多了 你的FastAPI又在服务器上“跑不起来”了?来,今天咱把打包这件事彻底聊透 写页面时别再把 Element Plus 整个搬进来啦!Vue3按需加载的坑我帮你踩平了 前端包管理咋选?我从npm叛逃到pnpm的血泪史(附避坑指南) 聊聊 fetch 使用中我踩过的那些坑和正确打开方式 FastApiAdmin 后端接口开发好了,前端管理界面怎么调用与显示? 给 FastApiAdmin 加个“会议纪要”模块,我把后端二次开发的坑踩了个遍 我用了FastApiAdmin后,连夜把踩过的坑都整理出来了 告别 Typora 后的新欢:我把所有笔记迁移到了 Obsidian 这个“第二大脑” 你的Agent API还在裸奔?从认证到沙箱,我用FastAPI搭了几道防线 让 FastAPI Agent 思考不阻塞:手把手教你实现异步任务与后台处理方案 让FastAPI Agent真正记住你:聊聊会话记忆与持久化存储的落地实践 FastAPI Agent 函数调用实战:我让 AI 学会了“自己动手查天气“ 初探:用 FastAPI 搭建你的第一个 AI Agent 接口 FastAPI 少有人提的实用技巧:把 Depends 依赖提到路由层,代码少写60% FastAPI 生产环境静态文件完全指南:从 /favicon.ico 404 到 HSTS 混合内容,一次全根治 用了loguru我才明白,Python日志还能这么写 FastAPI 后台任务:BackgroundTasks 的使用场景与注意事项 FastAPI配置管理避坑指南:从硬编码到 .env 与 pydantic_settings 类,连路由用法都给你捋清楚 FastAPI 文件上传避坑全指南:分块存盘、类型校验与安全兜底 FastAPI + Pydantic 模型终极实战手册:从能跑就行到固若金汤,这些技巧你一定用得上 FastAPI + SQLAlchemy 2.0 通用CRUD操作手册 —— 从同步到异步,一次讲透 FastAPI订单防超卖实战:从数据库锁到Saga分布式事务,这一篇给你理清了 FastAPI 生产环境避坑指南:用 Alembic 管理数据库迁移,别再手动改表结构了! FastAPI服务半夜又挂了?先别急着重启,查查你的数据库连接池“池子”是不是漏了 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 Vue 3 组合式 API 香是香,但从Vue2迁移时你可别像我当初一样踩进这 3 个深坑里 我用fastapi-scaff搭了个项目,两天工期缩到两小时,老板以为我开挂了 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! FastAPI自动生成的API文档太丑?我花了一晚上把它改成了客户愿意付费的样子 告别手写 API 胶水代码:FastAPI 与 Vue 的“契约自动机” OpenAPI 实战 FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南” FastAPI + Celery 实战:异步任务里调用 Redis 和数据库的全解析,及生产级组织方案 FastAPI里玩转Redis和数据库的正确姿势,别让异步任务把你坑哭了! FastAPI + Celery 实战:异步任务的坑与解法,我帮你踩了一遍 FastAPI子应用挂载:别再让root_path坑你一夜 FastAPI项目半夜报警吵醒你?聊聊告警这事儿怎么搞! 别再数据线了!用FastAPI 5分钟搭个局域网文件+剪贴板神器 FastAPI单元测试实战:别等上线被喷才后悔,TestClient用对了真香! FastAPI状态共享秘籍:别再让中间件、依赖和路由“各自为政”了! FastAPI实战:WebSocket vs Socket.IO,这回真给我整明白了! 从0到1,FastAPI + PostgreSQL + Tortoise ORM 实战避坑指南 FastAPI + PostgreSQL 实战:给应用装上“缓存”和“日志”翅膀 FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
FastAPI 身份验证总踩坑?这份 FastAPI Users “避坑指南”请收好
一名程序媛呀 · 2026-06-07 · via 博客园 - 一名程序媛呀

身份验证是每个后端项目的“第一道门”,但往往也是劝退新手的第一大坑。

本文不讲虚的,以一个全栈工程师的真实踩坑视角,带你梳理 FastAPI 身份验证与用户管理的最优解—— FastAPI Users 库,
从安装、实战到选型建议,一条龙拆解。

如果你正被 JWT、Cookie、数据库迁移搞得头秃,这篇“人话版”经验总结或许能让你少熬几个夜。


🤔 你被身份验证折磨过吗?

每次新起一个 FastAPI 项目,聊到登录注册、用户角色、Token 刷新这些话题,群里总是一片哀嚎。

明明 FastAPI 官方文档把请求体、依赖注入讲得明明白白,可一到身份验证,瞬间变成大型面向复制粘贴编程现场。

那一刻我就知道,身份验证这事儿,必须得有一套“开箱即用、又不容易犯蠢”的方案。

今天咱们不聊虚的,直接请出我们的主角——FastAPI Users
我会把它的安装、核心用法、常见坑,以及“到底该不该用”的选择建议,一口气跟你唠明白。

👩‍💻我是爱折腾的一名程序媛,喜欢研究全栈开发的各种实践,热爱分享踩坑后的收获与思考,也享受用代码写出各种实用小工具解决问题的快乐。

如果你也在技术这条路上向前走,关注我,愿我们能彼此陪伴,一起成为更好的自己 🌱


🎯 这篇文章能帮你解决什么

读完你会收获:

🔹 一套完整的 FastAPI 身份验证与用户管理落地方案

🔹 知道什么时候该用 FastAPI Users,什么时候不该用

🔹 避开数据库迁移、依赖冲突等新手高频踩坑点

🔹 直接可跑的代码片段和配置思路


📌 先搞清楚一个问题:为什么不用自己写?

你可能会问:“我照着教程手写 JWT 不香吗?”
香,但“缝缝补补”的成本远比想象的高。

用户注册时的邮箱校验、密码重置、Token 刷新、用户角色控制…… 每增加一个功能,你的 auth.py 文件就像在打补丁。

更要命的是,安全细节稍有不慎就是致命伤,比如 access_token 过期时间设得太长、refresh_token 没做轮换机制。

FastAPI Users 最让我心动的一点,就是把“最佳实践”封装成了可插拔的模块。
它不绑架你的数据库选择,也不逼你绑定某种前端框架,纯粹在 FastAPI 的依赖注入体系里,帮你搞定了用户管理的 90% 工作。


🧰 核心原理:它到底是怎么运作的?

好,咱们先来拆解一下架构,不用看源码也能懂。

FastAPI Users 本质上是一个依赖注入的集合:
你把用户数据库模型、认证后端(比如 JWT 或 Cookie)、密码哈希策略、邮件发送器等组件分别配置好,然后像乐高一样拼在一起。
它负责生成那些让你头疼的路由:
/register/login/forgot-password 等等。

打个比方,FastAPI 的路由是一个餐厅的出餐口,FastAPI Users 则直接给你预制了一套“顾客点餐、验证会员、找回会员卡”的标准化流程,
你只需要决定会员数据存哪里(SQLite、PostgreSQL 还是 MongoDB),以及会员卡用什么加密方式。

接下来重点来了,它的核心依赖关系:

🔹 用户模型 —— 你用 SQLAlchemy、Tortoise ORM 或 Beanie 定义的用户表

🔹 用户管理器 —— 负责创建、查询、更新用户

🔹 认证后端 —— JWT 策略 或 Cookie 策略,二选一

🔹 可选组件 —— 邮箱验证、角色管理、OAuth 第三方登录等

理解这四层关系,后面的实战配置就轻松了。


🛠️ 实战演示:从零搭一个带用户系统的 FastAPI

这里有一点要特别注意:版本兼容性
FastAPI Users 的 v10 以上和 v9 差别巨大,千万别对着旧教程盲目复制。咱们以当前稳定的 v12 版本为例。

安装核心库

打开终端,一行搞定:

uv add fastapi-users[sqlalchemy] fastapi uvicorn

这里我用 SQLAlchemy 做演示,因为它社区最广,坑最好找。如果你用 MongoDB,把方括号里换成 beanie 就行。

定义用户模型

工具的选择上,我认为顺手的才是最好的。既然选了 SQLAlchemy,咱们就用 DeclarativeBaseSQLAlchemyUserDatabase 的组合。

from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase

from sqlalchemy.ext.asyncio import AsyncSession

from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):

    pass

class User(SQLAlchemyBaseUserTable[int], Base):

    __tablename__ = "user"

    # 可以加自定义字段,比如 nickname

    nickname: str | None = None

配置用户管理器和认证后端

这里有个很容易翻车的点:一定要用异步引擎,否则和 FastAPI 的协程体系打架,你会看到奇怪的超时错误。

from fastapi_users import FastAPIUsers

from fastapi_users.authentication import JWTStrategy, AuthenticationBackend, BearerTransport

bearer_transport = BearerTransport(tokenUrl="auth/jwt/login")

def get_jwt_strategy() -> JWTStrategy:

    return JWTStrategy(secret="YOUR_SUPER_SECRET", lifetime_seconds=3600)

auth_backend = AuthenticationBackend(

    name="jwt",

    transport=bearer_transport,

    get_strategy=get_jwt_strategy,

)

fastapi_users = FastAPIUsers[User, int](

    get_async_user_manager,

    [auth_backend],

)

这里补充一下 get_async_user_manager 的定义,它是整个依赖注入链的核心

from fastapi import Depends

from fastapi_users import BaseUserManager, IntegerIDMixin

from sqlalchemy.ext.asyncio import AsyncSession

# 假设你已经有异步数据库会话依赖,通常长这样:

# async def get_async_session() -> AsyncSession:

#     async with async_session() as session:

#         yield session

class UserManager(IntegerIDMixin, BaseUserManager[User, int]):

    """你可以在这里重写密码校验、注册后处理等钩子"""

    # 比如:用户注册后你想自动发邮件,就覆盖 on_after_register 方法

    # async def on_after_register(self, user, request=None):

    #     print(f"用户 {user.email} 注册成功,准备发邮件")

async def get_user_db(session: AsyncSession = Depends(get_async_session)):

    yield SQLAlchemyUserDatabase(session, User)

async def get_async_user_manager(user_db: SQLAlchemyUserDatabase = Depends(get_user_db)):

    yield UserManager(user_db)

🔹 这里有几个踩坑点要再啰嗦一句

数据库会话必须走异步引擎,如果你用同步 Session,进 SQLAlchemyUserDatabase 会直接报类型错误,而且 FastAPI 的协程线程池混用容易出隐秘 bug。

IntegerIDMixin 表示用户主键是 int,如果你用 UUID,就换成 UUIDIDMixin,这个要和 User 模型里的 id 类型严格对应,不然路由生成的路径参数会错乱。

自定义 UserManager 类是埋钩子的最佳入口,比如你想在用户首次登录后强制改密码,覆盖 on_after_login 就行,别去改库源码。

挂载路由并保护接口

app.include_router(

    fastapi_users.get_auth_router(auth_backend),

    prefix="/auth/jwt",

    tags=["auth"],

)

app.include_router(

    fastapi_users.get_register_router(),

    prefix="/auth",

    tags=["auth"],

)

@app.get("/protected")

async def protected_route(user: User = Depends(current_active_user)):

    return {"message"f"Hello, {user.email}!"}

跑起来后,/auth/jwt/login 就能拿到 Token,/protected 配上 Authorization: Bearer <token> 就能访问了。
是不是以为这样就 Ok 了?哈哈,还没有。


⚠️ 再说几个容易翻车的点

🔹 数据库迁移一定要手动检查

FastAPI Users 的用户表虽然帮你定了基础字段,但如果你添加了自定义字段(比如上面的 nickname),启动时不会自动建表。

务必用 Alembic 生成迁移脚本,并检查 revision 是否正确。尽量不要直接在服务器上 create_all(),容易导致生产表结构一塌糊涂。

🔹 JWT Secret 千万别硬编码

上面示例里我写了 YOUR_SUPER_SECRET,那是为了演示。
真实项目请从环境变量读取,而且这个 secret 至少要 256 位随机字符串。

官方文档虽然这么说,但根据以往的经验,调整成 512 位用 secrets.token_urlsafe 生成会更稳。

🔹 Cookie 策略的坑

如果你需要 SSR 或纯网页应用,可能会选 Cookie 传输。
此时必须设置 cookie_secure=True 并且只能走 HTTPS,否则浏览器直接拒绝存储。
本地开发为了测试常常忘开,上线后就傻眼了。

🔹 用户角色和权限

FastAPI Users 自带的 superuser 标记只算个最低配权限。
一旦你的系统需要“普通用户、编辑、管理员”等多角色,建议配合 fastapi-permissions 或者自己写一个简单的依赖注入,不要魔改核心库。


💡 我到底该不该用 FastAPI Users?

我个人的主观偏好是:中小型项目、标准身份验证需求,闭眼用
它帮你省下的时间是实实在在的,而且社区活跃,踩坑有人一起填。

但如果你是以下情况,可能需要三思:

🔹 用户模型极其复杂,比如和很多遗留系统的表强耦合,改装成本大于自己写

🔹 只需要极简的 API Key 校验,不需要整套用户体系,引入完整的库反而重

🔹 使用非标准数据库,比如一些不常见的 NoSQL,可能适配起来不顺畅

最后啰嗦一句:
无论你用哪个库,密码的加密存储、Token 的短有效期、刷新令牌的轮换机制,这三条原则请你焊死在代码的 DNA 里。
安全不是附加题,是命根子。


🎁 总结一下

从身份验证的一地鸡毛,到用 FastAPI Users 优雅搭建用户系统,咱们今天聊的全是实战干货。
工具选对了,写代码的心情都会变好。希望你看完这篇文章后,不再对 FastAPI 的 auth 部分感到发怵,而是能自信地把它组装进自己的项目里。

如果你觉得这篇“人话版”指南有点用,别藏着掖着,点赞收藏加关注,防止下次想找的时候找不到~
你在身份验证上还踩过哪些坑?评论区唠一唠,一起避坑才是真朋友 🎯。