☰
不用 Redis,我用 Python 进程内存字典实现了验证码系统
2026/10/14 3:47:23 网站建设 项目流程

在做社区旧物互换平台时,用户注册和登录都需要验证码。最开始我也考虑过几种常见方案:把验证码存进数据库表、引入 Redis,或者直接调用第三方验证码服务。

但这个项目目前主要是本地开发和小范围演示,如果为了验证码专门引入 Redis,会增加部署复杂度;如果建一张verification_code表,又会产生大量短生命周期数据。于是最终我选择了一个更轻量的方案:在code_service.py中用一个进程内存字典_STORE来存储验证码。

为什么不用 Redis?

Redis 确实很适合做验证码缓存,支持过期时间、分布式共享、高并发访问。但对于当前阶段的项目来说,它有几个成本:

  • 需要额外安装和运行 Redis 服务;
  • 本地开发环境配置会变复杂;
  • 如果只是单实例、小规模使用,收益并不明显。

所以我的思路是:先把核心业务跑通,用进程内存字典降低开发成本。如果后续项目部署到多实例服务器,再考虑切换到 Redis。

为什么不用数据库表?

验证码本身有这几个特点:

  • 有效期很短,通常 5 分钟左右;
  • 校验通过后就应该失效;
  • 写入和读取都非常频繁;
  • 不需要长期保存。

如果把这些数据都写入数据库,会增加不必要的 IO 开销。而且验证码校验通过后还要删除或标记失效,表结构也会变得比较臃肿。

所以最后我决定:验证码只存在于内存中,不依赖 Redis,也不落库。

最终方案:code_service.py中的_STORE

我在code_service.py里定义了一个字典_STORE,用来保存验证码和发送时间。

当前平台的验证码规则是:

  • 验证码有效期:5 分钟
  • 发送间隔限制:60 秒内不能重复发送
  • 校验成功后:立即删除
  • 存储方式:进程内存字典_STORE

核心代码大致是这样的:

这里没有用第三方缓存库,而是直接在字典里存验证码和过期时间。每次校验时,先判断是否存在,再判断是否超过 5 分钟,最后比较验证码是否正确。

在 FastAPI 中怎么接入?

在 FastAPI 路由里,可以把验证码发送和校验逻辑封装成工具函数:

这样前端只需要传入邮箱或手机号,后端负责生成验证码、写入 _STORE、校验和删除。

这个方案的优点

  • 轻量:不需要安装 Redis,也不需要建表。
  • 开发快:本地启动 FastAPI 就能直接测试。
  • 适合短生命周期数据:验证码本来就不需要持久化。
  • 结构简单:一个字典就能完成存储、校验和清理。

需要注意的限制

这个方案也有明显边界:

  • 重启服务后验证码会丢失,因为数据只存在进程内存里;
  • 多实例部署时无法共享,每个进程有独立_STORE;
  • 需要手动清理过期数据,字典不会自动删除过期项;
  • 生产环境建议加监控,避免内存字典异常导致用户无法登录。

所以它更适合开发、测试、演示或单实例部署场景。如果项目后续用户量变大,或者需要多节点部署,我会考虑把验证码迁移到 Redis。

后续改进方向

目前这个验证码模块已经接入了平台的邮箱和手机号验证流程。后续可以继续完善:
接入真实 SMTP 邮箱服务;
接入短信服务商;
增加图形验证码,防止机器批量请求;
把验证码发送次数写入日志,方便排查异常;
在多实例部署时替换为 Redis 后端。

小结

这个验证码方案并不复杂,但它解决了一个很实际的问题:在没有 Redis、不想建表的情况下,如何快速实现一个可用的验证码系统。

对于学生项目、个人项目或早期原型来说,轻量方案往往更合适。先把核心流程跑通,再根据实际部署需求逐步升级,会比一开始追求“完美架构”更高效。

如果你也在做类似的全栈项目,欢迎交流你的验证码方案。下一篇我会继续分享这个平台的物品管理与数据库设计。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询