← 返回题目列表

小程序登录流程是怎样的?openid、unionid 和 session_key 有什么区别?

高频 困难 第 16 / 32 题 更新于 2026/07/28
小程序登录openidsession_key

简化版

小程序登录通常是前端调用 wx.login 获取临时 code,发送给后端,后端用 code 换取 openidsession_key,再生成自己的登录态返回给前端。openid 标识用户在当前小程序下的身份,unionid 在满足条件时可关联同一开放平台账号下的应用,session_key 用于微信会话校验及旧版加密数据流程,不应下发给前端。

详细版

典型流程:

  1. 小程序调用 wx.login 获取临时 code
  2. 前端把 code 发送给业务后端。
  3. 后端调用微信接口,用 code 换取 openidsession_key
  4. 后端根据 openid 查找或创建用户。
  5. 后端生成业务 token 或 session,返回给前端。
  6. 前端保存业务登录态,后续请求携带它。

几个概念:

  • openid:用户在某个小程序下的唯一标识。
  • unionid:满足返回条件时,用于关联同一开放平台账号下的多个应用。
  • session_key:微信侧会话密钥,用于会话校验及旧版加密数据解密,应保存在服务端;新版手机号动态 code 流程由后端换取数据。

完整版教学

一、为什么不能只靠前端登录

wx.login 返回的 code 只是临时凭证,不是用户身份本身。它需要由后端拿着小程序的 appid 和密钥去微信服务端换取用户标识。

如果把密钥放到前端,等于暴露应用凭证,存在严重安全风险。因此登录闭环必须有服务端参与。

二、openid、unionid、session_key 的区别

openid 是用户在当前小程序内的唯一标识。不同小程序之间,即使是同一个微信用户,openid 通常也不同。

unionid 用于同一开放平台账号主体下的多个应用打通用户身份。例如公众号、小程序、App 都绑定到同一开放平台主体时,可以用 unionid 判断是不是同一个微信用户。

session_key 是微信返回给后端的会话密钥,可用于微信会话相关校验及旧版 encryptedData 流程。它不是业务 token,也不应该直接发给客户端;具体敏感能力若已改为动态 code,应由后端按新接口换取。

三、业务登录态怎么设计

后端拿到 openid 后,一般不会直接让前端每次携带 openid 请求,而是生成自己的登录态,比如 JWT 或 session token。

这样有几个好处:

  • 可以加入业务用户 ID、角色、过期时间。
  • 可以统一管理登录失效。
  • 可以避免把微信侧细节暴露给前端。
  • 可以支持多端、多渠道登录体系。

前端只需要保存业务 token,并在请求头中携带。

四、面试追问与工程落地

面试官可能问:“session_key 能不能存在前端?”

不应该。session_key 用于解密微信敏感数据,如果泄露,可能带来隐私风险。正确做法是后端保存或短期使用它:历史 encryptedData 流程由后端解密;当前手机号动态 code 流程则由后端调用对应服务端接口换取,不能混用。

工程中还要处理 code 过期、token 过期、静默登录失败、用户拒绝授权等异常。登录不是一个 API 调完就结束,而是要设计完整的状态恢复流程。

五、凭证边界与完整时序

wx.logincode 是短期、一次性交换凭证,前端拿到后应尽快交给自己的后端,不能把它当业务 token 缓存复用。后端通过微信的 code2Session 接口交换身份信息时需要 appidAppSecret,所以该调用只能发生在可信服务端。

小程序 wx.login
      │ 临时 code

业务后端 ── code + AppSecret ──> 微信服务端
      │ <── openid + session_key ──
      │ 查/建业务用户,签发业务 session

小程序只保存业务登录态
数据谁签发/返回应保存位置用途
codewx.login短暂存在客户端仅用于服务端换取微信会话
openid微信服务端业务后端当前小程序内识别用户
unionid微信服务端,满足条件时业务后端同开放平台账号下合并身份
session_key微信服务端业务后端微信会话相关校验/旧流程解密
业务 token业务后端客户端受控存储访问自己的业务接口

例如业务 token 设计为 2 小时、刷新凭证 7 天只是一个可讨论的产品方案,不是微信平台固定值。短 token 缩小泄露窗口,刷新机制改善体验;服务端仍要支持封禁、退出和设备风险发生时主动撤销。

六、新旧敏感数据流程与账号合并

要区分历史上的 encryptedData + iv + session_key 解密流程和当前某些能力返回动态 code 的流程。以新版手机号能力为例,前端在用户主动触发后取得动态 code,后端再用服务端接口换手机号;不能把所有手机号获取都回答成“把 session_key 发给前端解密”。具体能力应以对应基础库和开放文档为准。

unionid 不是每次登录都必然返回,只有应用满足开放平台绑定等条件且处于支持场景时才可获得。业务库应以自己的 user id 为主键,建立 (appid, openid) 唯一映射;拿到 unionid 后再执行可审计的账号合并,避免把缺失 unionid 的用户误合并。

登录接口还要防止会话固定和重放:成功交换 code 后创建新业务会话,不接纳客户端指定的用户 id;绑定手机号、修改资料等操作重新校验当前业务身份。若 100 个并发请求同时发现“用户不存在”,数据库唯一约束和事务必须保证只创建一个用户记录。

安全心法:AppSecretsession_key 不出服务端,openid 不是授权凭证,真正访问业务资源还要验证业务登录态和资源权限。

七、常见误区与追问

  • 误区:wx.login 成功就代表用户已经登录业务系统。 它只拿到临时 code,必须由后端完成交换、用户映射和业务会话签发。
  • 误区:openid 可以直接作为接口鉴权 token。 openid 只是标识符,不证明当前请求者拥有该身份,客户端提交的 openid 可被篡改。
  • 误区:unionid 在所有小程序登录中都会返回。 它受开放平台绑定和具体返回条件限制,业务必须兼容缺失情况。
  • 追问:session_key 为什么不能返回前端? 它属于微信会话机密,泄露会破坏相关数据校验或旧流程解密的安全边界。
  • 追问:新版手机号获取还需要前端解密吗? 动态 code 流程由后端调用服务端接口换取手机号,不应套用旧版客户端传 encryptedData 的固定答案。
  • 追问:code 交换失败如何处理? 不签发业务 token,区分过期、已使用、网络和配置错误,必要时重新调用 wx.login,同时记录可诊断但不含密钥的日志。
  • 追问:同一用户有多个小程序 openid 怎么合并? 在满足条件时用 unionid 建立关联,再映射到统一业务 user id,并处理历史账号冲突。

八、加强记忆

登录流程按“两次换票”记:客户端用 wx.login 拿临时 code,后端用 code 换微信身份,再由后端签发自己的业务登录态。openid 管单个 appid 下的身份,unionid 在满足条件时跨同一开放平台账号关联,session_key 留在服务端;手机号等敏感能力还要区分动态 code 新流程和历史解密流程。