微信小程序登录在iris中必须分两步:前端调用wx.login()获取code并发送至iris接口;iris接收code后调用微信auth.code2session换取openid和session_key,再缓存session_key用于后续解密手机号等操作。

微信小程序登录流程在 Iris 中必须拆成两步走
Iris 本身不处理前端 wx.login(),它只负责接收 code 并调用微信 auth.code2Session 接口。你不能把 wx.login() 放在 Iris 里调——那是小程序客户端行为。后端唯一要做的,就是提供一个接收 code 的 POST 接口,然后用它换 openid 和 session_key。
常见错误是试图在 Iris 中发起 wx.login() 调用,或者把前端用户信息(如 nickName、avatarUrl)直接当身份凭证存库——这些字段前端可伪造,不可信,仅作展示用。
- 前端必须先调用
wx.login()获取code,再通过wx.request发送到你的 Iris 接口 - Iris 接口收到
code后,拼接 URL:https://api.weixin.qq.com/sns/jscode2session?appid=xxx&secret=xxx&js_code=xxx&grant_type=authorization_code - 务必用
http.Client带超时控制发起请求,别用默认无超时的http.Get - 响应中若含
errcode字段(如40029),说明code无效或已使用过,需原样返回给前端提示重试
用 iris.Context.BindJSON 解析前端传来的 login 请求体
微信小程序登录接口通常接收 JSON body,例如:
{"code":"0e36jkGa1ercRF0Fu4Ia1V3fPD06jkGW","nickName":"张三","phoneCode":"13fe315872a4fb9ed3deee1e5909d5af60dfce7911013436fddcfe13f55ecad3"}
注意:nickName 和 phoneCode 是前端附加字段,Iris 不需要校验它们是否真实,但得能解析出来用于后续逻辑(比如写入日志、触发绑定手机号流程)。phoneCode 很可能是前端对手机号加密后的结果,和微信无关,别误以为是微信返回字段。
- 定义结构体时,字段名要和 JSON key 一致,且首字母大写 +
json:"xxx"tag - 用
c.BindJSON(&req),不要用c.PostForm或c.FormValue——那是处理表单的 - 如果前端没传
code,BindJSON会静默失败,必须手动检查req.Code == ""并返回 400 - 别忘了设置路由:
app.Post("/customer/user/login", loginHandler)
解密手机号需在服务端完成,且依赖 session_key
前端调用 wx.getPhoneNumber 获取加密数据后,必须把 encryptedData、iv 和之前登录拿到的 session_key 一起发给 Iris。Iris 用这三个值才能解出真实手机号——这个过程不能在前端做,session_key 绝对不能泄露给前端。
Go 标准库没有内置 AES-128-CBC 解密微信数据的 helper,得自己写或引入轻量工具(如 golang.org/x/crypto/aes + golang.org/x/crypto/cipher)。别用第三方“微信 SDK for Go”,多数已停止维护且硬编码了过时的 API 地址。
-
session_key必须从上一步code2Session响应中提取并缓存(比如用sync.Map存 5 分钟),不能每次解密都重新请求微信 - 解密失败常见原因:
iv长度不是 16 字节、encryptedData不是 base64 编码、session_key已过期或被重复使用 - 解密成功后得到的是 JSON 字符串,包含
phoneNumber字段,这才是真实可用的号码
若依框架集成时,sys_wechat_user 表的写入时机很关键
若依已有 sys_user 表,微信登录的核心是把 openid 关联到某个 user_id。这个关联不能在首次登录就盲目插入新用户——得先查 sys_wechat_user 表有没有该 openid,有则取对应 user_id;没有才新建用户并插入关联记录。
容易踩的坑是:前端多次快速点击登录按钮,导致并发写入同一 openid,引发唯一索引 uk_openid 冲突。Iris 层无法靠事务自动重试,必须在 SQL 层用 INSERT IGNORE 或应用层加锁(如 sync.Once 不适用,并发场景得用分布式锁或数据库唯一约束兜底)。
- 插入
sys_wechat_user前,先SELECT user_id FROM sys_wechat_user WHERE openid = ? - 若查不到,再执行
INSERT INTO sys_wechat_user (user_id, openid, unionid, nickname, avatar) VALUES (?, ?, ?, ?, ?) -
unionid只有在小程序绑定开放平台后才返回,不要假设它一定存在 -
nickname和avatar来自前端,必须过滤掉 XSS 字符(如<script></script>),哪怕只是存日志也得防
最常被忽略的一点:微信返回的 session_key 有效期只有 2 小时,且同一 code 只能换一次。如果你的登录态(比如 JWT)有效期设为 7 天,那后续所有需要解密的操作(如获取手机号)都必须依赖当时缓存的 session_key,而不是重新请求微信——否则必然失败。











