拿不到unionid的根本原因是微信开放平台未绑定或用户无历史行为。需确认小程序已绑定开放平台,且用户曾在同主体其他应用登录或关注,否则code2session仅返回openid。

uni-app 调用 wx.login 拿不到 UnionID?先看主体和绑定状态
绝大多数“拿不到 UnionID”的问题,根本不是代码写错了,而是微信平台侧的前置条件没满足。UnionID 不是默认返回的字段,它依赖微信开放平台的统一身份绑定关系。
关键判断点只有两个:
• 你的小程序 appid 是否已绑定到「微信开放平台」账号下(不是公众号后台,也不是小程序管理后台);
• 用户是否已在同一主体下的其他应用(如公众号、App、另一个小程序)完成过微信登录或关注行为。
- 如果小程序未在开放平台绑定 →
code2Session返回里永远没有unionid字段,哪怕用户已授权也没用 - 如果用户是第一次访问你家所有应用 → 即便绑定了开放平台,
wx.login+code2Session也只返回openid,unionid为空 - 用户曾关注过你家公众号,或在你家 App 登录过 → 同一微信 ID 再次调用
code2Session就会带出unionid
静默获取 UnionID 的三种可行路径(不弹授权框)
用户不点按钮、不触发 bindgetuserinfo,也能拿到 UnionID —— 但每种都有明确适用边界,不能混用。
-
支付后调用
getPaidUnionID:仅限已完成支付的用户,且需后端调用微信订单查询接口再换 UnionID,前端无法直接触发 -
开放平台已绑定 + 用户已有历史行为:此时
wx.login→ 后端js_code2session就能静默拿到unionid,这是最干净的方案 -
云开发场景用
Cloud.getWXContext():仅限 uniCloud 阿里云/腾讯云环境,且需开启「登录态校验」,函数内直接取event.unionId,无需自己请求微信接口
注意:wx.getUserInfo 解密方式已被微信逐步限制,2026 年起新提审小程序基本无法通过该方式静默获取 UnionID,除非用户主动点击授权按钮。
uni-app 前端调用 wx.login 的典型错误写法
很多人把 uni.login 和 wx.login 混用,或者在错误时机发起请求,导致 code 拿不到、过期、重复使用。
- 在
onLoad或页面渲染后才调uni.login→ 用户可能已经跳走,code 来不及传给后端 - 在
onLaunch中调用但没做 storage 缓存 → 页面刷新后 code 丢失,又没重试逻辑 - 把
uni.login的 success 回调当同步执行 → 实际是异步,code一拿到就得立刻发请求,延迟 > 5 分钟就失效 - 多个页面都调
uni.login→ 同一 session 可能被覆盖,后端解出来的 openid 对不上
建议统一收口到 app.vue 的 onLaunch + onShow,用 uni.setStorageSync('loginCode', code) 缓存,并加时间戳标记有效期。
Spring Boot 后端解析 code 时最容易漏掉的配置
前端 code 传过来,后端用 RestTemplate 或 WebClient 请求微信接口,看似简单,但几个细节不处理就会一直收不到 unionid。
- 请求地址必须是
https://api.weixin.qq.com/sns/jscode2session,不是公众号的https://api.weixin.qq.com/sns/oauth2/access_token -
grant_type=authorization_code必须小写,大写或空格会导致返回 400 且无提示 - 微信返回的是 JSON,但字段名是全小写(
openid,session_key,unionid),Java DTO 里字段名对不上就自动忽略unionid - 没检查返回体是否含
errcode字段 → 微信出错时返回的是错误 JSON(如{"errcode":40029,"errmsg":"invalid code"}),而不是正常字段,直接反序列化会丢异常信息
真正卡住人的,往往不是算法或加密,而是这些微信接口返回格式和状态码的隐性约定。











