1 引言
1.1 背景
使用微信扫码登录具对用户来说具备极大的便利性。 但是对于集成微信登录的站点来说,需要一些门槛。比如需要认证、需要企业认证、需要开发者认证等。
另一种使用微信扫码登录的方式是通过访客关注公众号的形式来实现的。从理论上来说这是一种最佳的方式,一方面对用户来说使用便捷,另一方面对站点来说也可以和公众号联合运营。 但是这种方式仍存在很大的门槛。 认证只是其中一个,最为主要的可能就是他只支持服务号,不支持订阅号。 如果一些站点运营订阅号很长时间了,积累了自己的关注者,要是因为要实现扫码登录而重新起一个服务号,那就有点不合适了。
本系统将实现一种全新的无任何门槛的使用微信订阅号登录网站的方案,通过微信公众号的消息接收与转发,实现用户登录网站的需求。对比传统的公众号登录方案来说最大的优势在于用户无需认证,只需关注公众号并发送验证码即可登录网站。
1.2 目的
本文档旨在定义“微信订阅号验证码登录系统”的功能与非功能需求,明确系统边界、用户流程、接口规范及安全要求,为后续设计、开发与测试提供依据。
该系统允许用户通过关注微信订阅号并发送验证码的方式完成网站登录,适用于未认证或仅拥有订阅号的项目,解决传统微信登录对服务号和企业认证的依赖问题。
1.3 范围
本系统包含以下核心组件:
- 网站前端登录页面
- 后端验证码生成与验证服务
- 微信公众号消息接收与转发逻辑
- 用户身份绑定与会话管理
系统不包含微信公众号的创建、认证或内容运营功能。
1.4 术语定义
术语 | 定义 |
---|---|
OpenID | 微信用户在公众号下的唯一标识符 |
验证码(Challenge Code) | 5位随机数字,用于临时关联用户与登录会话 |
公众号API服务 | 接收微信服务器POST消息的服务端接口 |
Token | 登录成功后生成的JWT或Session令牌 |
1.5 参考资料
- 微信公众号开发者文档
- 原始设计文章:https://srs.pub/miscellaneous/wechat-mp-login.html
2 总体描述
2.1 用户角色
角色 | 描述 |
---|---|
普通用户 | 使用微信关注公众号并通过发送验证码登录网站 |
开发者 | 配置公众号接口、实现后端服务与前端逻辑 |
运营人员 | 管理公众号内容,查看用户增长数据 |
2.2 系统上下文

2.3 运行环境
- 前端:现代浏览器(Chrome, Firefox, Safari, Edge)
- 后端:Node.js / Python / Java 等支持HTTP服务的语言
- 数据库:MySQL / PostgreSQL(存储用户信息)
- 缓存:Redis(存储验证码映射关系)
- 公众号服务器配置:公网可访问的HTTPS接口
3 功能需求
3.1 生成登录验证码(FR-001)
- 描述:用户访问登录页时,系统应生成一个唯一的5位纯数字验证码。
- 触发条件:用户打开
/login
页面。 - 处理流程:
- 生成5位随机整数(范围:10000–99999)。
- 将验证码作为 key,关联一个临时会话 ID(session_id)存入 Redis,有效期设置为 300秒(5分钟)。
- 返回响应:
{
"code": "82736",
"qrcode_url": "https://mp.example.com/qrcode.jpg",
"expires_in": 300
}
- 异常处理:
- 若生成失败,返回 HTTP 500 错误。
3.2 显示登录引导界面(FR-002)
- 描述:前端展示验证码、公众号二维码及操作指引。
- UI要素:
- 大号字体显示验证码(如:
82736
) - 公众号二维码图片
- 文案提示:“请使用微信扫码关注公众号,并将上方验证码发送给公众号”
- 倒计时显示:“验证码将在 5:00 后失效”
- “重新获取”按钮(可刷新验证码)
3.3 接收微信消息并验证(FR-003)
- 描述:公众号API服务接收微信服务器推送的消息,识别验证码并触发验证。
- 接口要求:
- URL:
https://your-api.com/wechat/message
- 支持 POST 方法,Content-Type:
application/xml
- 消息解析规则:
- 解析XML中的
<Content>
字段。 - 若内容为5位纯数字,则视为验证码。
- 提取
<FromUserName>
作为用户的 OpenID。 - 验证流程:
- 调用内部接口
POST /api/verify-code
,携带参数:
{ "code": "82736", "openid": "oABC123..." }
- 根据返回结果决定回复内容:
- 成功 → 回复文本:“登录成功!请返回网站。”
- 失败 → 回复:“验证码错误或已过期,请检查后重试。”
3.4 验证验证码并创建会话(FR-004)
- 描述:后端服务验证用户提交的验证码,并建立用户身份绑定。
- 接口:
POST /api/verify-code
- 输入参数:
{ "code": "82736", "openid": "oABC123..." }
- 处理逻辑:
- 查询 Redis 是否存在该验证码。
- 若存在:
- 删除该验证码(防重放)
- 查询数据库是否存在该 OpenID 的用户记录
- 存在 → 获取用户ID
- 不存在 → 创建新用户,绑定 OpenID
- 生成 JWT Token 或 Session Cookie
- 将
session_id
与token
关联存储(Redis),有效期30分钟 - 返回成功响应:
{ "success": true, "token": "xxxx.yyyy.zzzz", "user_id": 123 }
- 若不存在 → 返回
{ "success": false, "error": "invalid_code" }
3.5 前端轮询登录状态(FR-005)
- 描述:前端定时查询验证码是否已被验证。
- 接口:
GET /api/login/status?code=82736
- 响应:
- 未验证:
{ "status": "pending" }
- 已验证:
{ "status": "success", "token": "xxxx.yyyy.zzzz" }
- 过期:
{ "status": "expired" }
- 轮询策略:
- 每 3 秒一次
- 最多尝试 100 次(约5分钟)
- 获取 token 后停止轮询,设置本地认证状态并跳转首页
3.6 用户身份管理(FR-006)
- 描述:系统需维护用户与微信 OpenID 的绑定关系。
- 数据结构:
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
VARCHAR(100) UNIQUE NOT NULL,
openid VARCHAR(50),
nickname
avatar_url TEXT,DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME
last_login DATETIME );
- 行为:
- 首次登录自动创建用户
- 后续登录更新
last_login
时间 - 支持通过 OpenID 查询用户信息
4 非功能需求
4.1 安全性
- 所有接口必须使用 HTTPS
- 验证码必须一次性使用,使用后立即失效
- 防刷机制:同一 OpenID 每分钟最多尝试 3 次验证
- Redis 缓存设置合理过期时间,防止内存泄漏
- 不在日志中记录验证码明文
4.2 性能
- 验证码生成与查询响应时间 < 100ms
- 消息接收接口响应时间 < 500ms(微信要求)
- 支持每秒处理 10+ 登录请求(中等规模应用)
4.3 可靠性
- Redis 故障时应有降级机制(如临时使用内存缓存)
- 公众号消息接收需有重试机制(微信可能重发消息)
- 日志记录关键操作:验证码生成、验证成功/失败、用户创建
4.4 可维护性
- 模块化设计:验证码模块、用户模块、微信接口模块分离
- 提供健康检查接口
/healthz
- 所有配置项(如过期时间、公众号Token)通过环境变量注入
5 接口定义(摘要)
接口 | 方法 | 描述 |
---|---|---|
/api/login/challenge |
GET | 获取新验证码 |
/api/login/status |
GET | 查询验证码状态 |
/api/verify-code |
POST | 验证验证码(内部/公众号调用) |
/wechat/message |
POST | 接收微信消息(公众号回调) |
/api/user/profile |
GET | 获取当前用户信息(需认证) |
6 状态转换图

7 附录
7.1 实际应用案例
- 项目名称:sxo.cc 商业模式画布 1平台
- 登录地址:http://sxo.cc/bmc
- 公众号类型:未认证个人订阅号
- 技术栈:Apache + PHP + MySQL
7.2 已知限制
- 不支持一键登录,用户体验略低于标准扫码
- 依赖用户手动输入验证码,存在操作失误风险
- 无法获取用户昵称/头像(除非用户曾与公众号互动)
7.3 后续优化建议
- 增加图形验证码辅助验证
- 支持语音输入或粘贴优化体验
- 添加登录成功后公众号自动推送欢迎消息
审批记录
角色 | 姓名 | 日期 | 签名 |
---|---|---|---|
产品经理 | |||
技术负责人 | |||
安全工程师 |
📄 文档状态:草案(Draft) © 2025 三恒移俗. 保留所有权利。
作者: