logo
0
0
WeChat Login
增加说明文档

微信扫码登录方案 - 完整实现

🎯 方案说明

这是一个反向扫码登录方案,解决了电脑浏览器无法扫描二维码的问题。

核心思路:

  • 网站主动发起登录 (而不是小程序传递token)
  • 用户用微信扫描网站生成的二维码
  • 小程序确认登录后,网站通过轮询获取登录状态

🔄 完整流程

┌─────────────┐ │ 1. 网站请求 │ POST /api/session/create │ 创建会话 │ 返回: sessionId └──────┬──────┘ │ ↓ ┌─────────────┐ │ 2. 网站展示 │ 生成二维码 │ 二维码 │ 内容: https://site.com/scan?sessionId=xxx └──────┬──────┘ │ ↓ ┌─────────────┐ │ 3. 网站轮询 │ GET /api/session/poll/:sessionId │ 登录状态 │ 每2秒查询一次 └──────┬──────┘ │ ↓ (同时进行) │ ┌──────────────┐ │ 4. 用户扫码 │ 微信扫一扫 │ 打开小程序 │ 跳转到 pages/scan-login/scan-login?sessionId=xxx └──────┬───────┘ │ ↓ ┌──────────────┐ │ 5. 小程序 │ - 用户填写/确认信息 │ 确认登录 │ - 调用 wx.login() 获取 code │ │ - POST /api/session/bind └──────┬───────┘ │ ↓ ┌──────────────┐ │ 6. 后端处理 │ - 用 code 换 openid │ │ - 生成 token │ │ - 更新会话状态为 confirmed └──────┬───────┘ │ ↓ ┌──────────────┐ │ 7. 网站轮询 │ - 检测到状态为 confirmed │ 检测到登录 │ - 获取 token │ │ - 设置 cookie │ │ - 跳转到首页 └──────────────┘

📦 已创建的文件

后端 Go 文件:

小程序文件:

🚀 使用步骤

1. 后端设置

安装依赖

go get github.com/gin-gonic/gin go get github.com/google/uuid go get gorm.io/gorm go get gorm.io/driver/mysql

创建数据库表

-- 用户表(已存在) CREATE TABLE `users` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `open_id` varchar(100) NOT NULL, `union_id` varchar(100) DEFAULT NULL, `nick_name` varchar(100) DEFAULT NULL, `avatar_url` varchar(500) DEFAULT NULL, `create_time` datetime(3) DEFAULT NULL, `last_login_time` datetime(3) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `open_id` (`open_id`), KEY `idx_users_union_id` (`union_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 登录会话表(新增) CREATE TABLE `login_sessions` ( `id` varchar(50) NOT NULL, `token` varchar(1000) DEFAULT NULL, `status` varchar(20) DEFAULT 'pending', `user_id` bigint unsigned DEFAULT NULL, `create_time` datetime(3) DEFAULT NULL, `expire_time` datetime(3) DEFAULT NULL, `scanned_at` datetime(3) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_status` (`status`), KEY `idx_expire_time` (`expire_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

运行后端

go run backend-scan-login.go

2. 访问网站登录页面

打开浏览器访问:

http://localhost:8080/wxamp/login

你会看到一个登录页面,显示二维码。

3. 微信扫码

使用微信扫一扫功能扫描二维码(注意:需要配置小程序二维码跳转)。

4. 小程序确认登录

扫码后会打开小程序的确认登录页面:

  • 如果已登录过,直接显示头像昵称
  • 如果首次登录,需要选择头像和输入昵称
  • 点击"确认登录"按钮

5. 网站自动登录

小程序确认后,网站会自动:

  • 检测到登录成功
  • 设置登录 cookie
  • 跳转到 /dashboard

🔑 核心API说明

1. 创建登录会话

POST /wxamp/api/session/create Response: { "success": true, "data": { "sessionId": "uuid-string", "qrCodeURL": "pages/scan-login/scan-login?sessionId=xxx", "expireTime": 1234567890 } }

2. 轮询登录状态

GET /wxamp/api/session/poll/:sessionId Response: { "success": true, "data": { "status": "confirmed", // pending | scanned | confirmed | expired "token": "jwt-token-string", "userId": 123 } }

3. 绑定会话(小程序调用)

POST /wxamp/api/session/bind Request: { "sessionId": "uuid-string", "code": "wx-login-code", "userInfo": { "nickName": "用户昵称", "avatarUrl": "头像URL" } } Response: { "success": true, "data": { "token": "jwt-token-string", "userInfo": { ... } } }

🎨 网站登录页面特性

  • ✅ 自动生成二维码
  • ✅ 实时轮询登录状态
  • ✅ 状态提示(等待扫码 → 已扫描 → 登录成功)
  • ✅ 二维码过期自动刷新
  • ✅ 登录成功自动跳转

📱 小程序页面特性

  • ✅ 自动读取 sessionId 参数
  • ✅ 支持新用户注册(头像+昵称)
  • ✅ 已登录用户直接确认
  • ✅ 绑定成功后返回
  • ✅ 优雅的错误处理

🔐 安全机制

  1. 会话过期: 10分钟自动过期
  2. Token签名: JWT签名防伪造
  3. 一次性会话: 每次扫码生成新会话
  4. 状态验证: 多重状态检查
  5. 自动清理: 定时清理过期会话

⚠️ 注意事项

关于小程序二维码

问题: 普通二维码无法直接打开小程序

解决方案有3种:

方案A: URL Scheme (推荐)

// 网站生成URL Scheme const scheme = `weixin://dl/business/?t=${encodeURIComponent('your_scheme')}` // 需要在微信公众平台配置 URL Scheme

方案B: 小程序码(需要后端生成)

// 调用微信接口生成小程序码 func generateMiniProgramCode(sessionId string) ([]byte, error) { url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + getAccessToken() body := map[string]interface{}{ "scene": "sessionId=" + sessionId, "page": "pages/scan-login/scan-login", "width": 280, } // 返回二维码图片 }

方案C: 短链跳转(临时方案)

网站二维码 → 短链 → H5页面 → 判断微信环境 → 跳转小程序

开发环境测试

由于无法生成真实小程序码,开发环境可以:

  1. 手动在小程序输入 sessionId
  2. 或在小程序添加测试入口
  3. 或使用微信开发者工具的二维码编译功能

生产环境配置

  1. 域名配置: 在微信公众平台配置服务器域名
  2. HTTPS: 生产环境必须使用HTTPS
  3. URL Scheme: 配置小程序的URL Scheme
  4. 业务域名: 配置H5业务域名(如果使用H5跳转)

🧪 测试流程

方法1: 直接测试小程序页面

  1. 运行后端
  2. 在微信开发者工具打开小程序
  3. 手动编译到 pages/scan-login/scan-login?sessionId=test-123
  4. 同时在浏览器打开 http://localhost:8080/wxamp/login
  5. 查看网站是否检测到登录

方法2: 完整流程测试

  1. 实现小程序码生成接口
  2. 网站访问 /wxamp/login
  3. 获取二维码
  4. 微信扫码
  5. 确认登录
  6. 网站自动登录

📊 数据库会话状态

状态说明
pending等待扫码
scanned已扫码,等待确认
confirmed已确认,登录成功
expired已过期

💡 优化建议

  1. WebSocket替代轮询: 使用WebSocket实现实时通知,减少服务器压力
  2. Redis缓存: 将会话数据存入Redis,提高查询性能
  3. 二维码美化: 添加logo,使用彩色二维码
  4. 多端支持: 同时支持APP、H5、PC
  5. 统计分析: 记录扫码、登录转化率

🔗 相关文档


这个方案完美解决了电脑浏览器无法扫码的问题!🎉