“目标不是又一个JWT登录教程项目。”AuthCore的构建者在它的技术博客中这样写道。他们要的是一个安全敏感、行为足够真实的身份与访问管理后端服务,迫使团队直面令牌生命周期、失败处理、审计纪律和运维证据。这个名为AuthCore的项目,用FastAPI搭骨架,塞进了PostgreSQL、Redis、Celery、Alembic、Docker、GitHub Actions和Trivy,把“生产级”三个字烙在了每一行代码里。
架构图很直白:客户端请求先撞上Uvicorn驱动的FastAPI应用,身后是四员大将。PostgreSQL负责存储用户、会话、令牌家族、MFA配置、RBAC角色和审计日志,所有持久化的命根子都在这儿。Redis扛起速率限制计数器、登录失败计数器和锁机状态,把热点数据挡在数据库门外。Celery作为后台任务地基,目前只用来递送邮件,但明摆着留着给日后任何异步动作。最后,一条GitHub Actions CI流水线严阵以待,依次跑Ruff lint、Black格式检查、带Postgres和Redis服务的Docker Compose测试、80%覆盖率门禁、Docker镜像构建和Trivy严重漏洞扫描。这条线断一次,就别想合入。
路由表划分得很清楚。认证部分的三条POST:注册、登录和刷新令牌;MFA部分四条:初始化设置、验证、禁用和挑战验证;会话部分供用户查看或删除自己的会话;管理员路由只有超级用户能碰,管着RBAC角色和审计日志查询。整张表没有一条多余的路由,但也把日常IAM需要的口子开齐了。
注册流程的开场是邮箱归一化。紧接着密码策略上场:至少12字符,小写、大写、数字、符号一个不落,直接怼掉常见弱密码和含邮箱用户名的字符串。如果开启了泄露检查,AuthCore会调 HaveIBeenPwned 的 k-anonymity 接口——只发送密码SHA-1哈希的前5个字符,原始密码从未离开系统。通过检查的明文再用bcrypt加盐哈希,然后创建用户、生成初始会话、签发访问令牌和刷新令牌,最后写一条审计事件。这环环相扣的7步,没有一步是纯粹为了跑通而写。
登录时先查Redis锁机状态,一旦锁了直接甩回423 StatusCode。没锁就验密码:失败则递增Redis计数器、写失败审计事件、返回401;成功就把计数器清零。接下来的岔路在于MFA。如果用户没启用MFA,立马发放两枚令牌。如果启用了,只返回一个短生命的MFA挑战令牌,必须等用户输完TOTP验证码并通过验证后,才能拿到完整的访问和刷新令牌。这意味着即使密码泄露,攻击者没有TOTP设备照样进不去。
为刷新令牌加上家族和重用检测,是AuthCore最硬核的一块。访问令牌短命,刷新令牌长命,后者因此需要更严的管教。每个令牌家族同时只有一个合法刷新令牌——最新签发的那枚。轮换时,客户端呈上刷新令牌,服务端验签后,拿它的哈希去和库里该家族最新哈希比对:匹配就签发新令牌、新刷新令牌,更新哈希;不匹配——也就是有人拿旧令牌重放——立刻废掉整个家族,写审计事件,返回401。值得注意的一个实现细节:生成HTTP异常前的失败审计事件,是在抛异常之前显式提交的。在FastAPI里,这个顺序保证了哪怕请求被异常打断,审计记录已经落盘,不会跟着回滚一起消失。
从注册时的密码泄露检测,到登录时的锁机和挑战令牌,再到刷新令牌的家族重用检测,AuthCore把IAM服务里那些通常被演示项目跳过的角落一一照亮。它不是又一个教你生成JWT的教程,而是一份用真实行为逼着自己做安全决策的答卷。
热门跟贴