Skip to content

小程序授权的“前世今生”:从“静默授权”到“手机号授权”

想当年,小程序刚问世时,大家普遍认为它“即开即用,即用即走”。然而,随着业务场景的不断丰富,我们逐渐意识到,许多功能都需要识别用户身份,例如个性化推荐、用户数据分析,乃至更高级的社交互动。于是,授权便成为了一个无法回避的核心议题。

所谓授权,简而言之,就是小程序在获取您的个人信息前,必须征得您的明确同意。这不仅是保护用户隐私的法律要求,更是小程序提供优质服务的根基。在授权的“江湖”中,有两位“大侠”举足轻重:一位是“低调内敛”的静默授权,另一位则是“光明磊落”的手机号授权。

静默授权:用户无感的“魔法”

或许你已经发觉,有些小程序你一进去,啥也没点,它就已经知道你是谁了?别慌,这不是什么黑科技,这就是咱们的“静默授权”在默默发功!

什么是静默授权?

静默授权,顾名思义,就是用户在无感知的情况下完成的授权过程。它主要用于获取用户的唯一标识 openid。openid 是什么?你可以把它理解为微信给每个用户在特定小程序里的一个“身份证号”。这个身份证号是匿名的,无法直接关联到你的真实身份,但对于小程序来说,它足以区分不同的用户,并进行一些基础的用户管理和数据统计。同时在手机号授权的配合下可以做到永久无感登录,这个我们后面会讲。

为什么说它“无感”?

因为整个过程不需要用户点击任何按钮,也不会弹出任何授权提示框。它通常在小程序启动时,或者在调用某些需要 openid 的API时自动触发。这对于提升用户体验简直是“神来之笔”,用户不用被打扰,就能享受到个性化服务。

静默授权的额外“福利”:省钱!

除了用户体验上的优势,静默授权现在还有个更实际的好处——省钱

是的,你没听错。随着微信小程序政策的调整,手机号授权现在是需要收费的(具体收费标准请参考微信官方文档)。而静默授权获取 openid 的过程,目前是免费的。这意味着,如果你只需要识别用户身份,而不需要用户的真实手机号,或者你像下面提到的 静默和手机号打通。那么选择静默授权可以为你节省一笔不小的运营开支。这对于预算有限的开发者来说,无疑是一大利好!

静默授权如何获取“系统用户信息”?

这里所说的“系统用户信息”,主要是指用户的 openid (以及在特定情况下的 unionid)。静默授权能够获取这些信息,其原理在于:

  1. 微信生态的内置能力:当用户通过微信启动小程序时,微信客户端已经确认了用户的身份。wx.login() 接口的实质,是小程序向微信服务器发起请求,以确认当前用户的身份,并换取一个临时的登录凭证 code
  2. code 的唯一性与安全性:此 code 由微信服务器根据当前用户与小程序的会话动态生成,具有临时性、一次性的特点,并与用户的微信身份紧密绑定。
  3. 后端安全验证:小程序前端在获取 code 后,无法直接解析出 openid。它必须将 code 发送至您的开发者服务器(后端)。随后,您的后端将使用小程序的 AppID 和仅存储于后端的 AppSecret,去调用微信的 auth.code2Session 接口。
  4. 微信服务器作为“认证中心”:微信服务器在接收到携带 codeAppIDAppSecret 的请求后,会执行严格的校验。校验成功后,服务器将返回对应的 openidsession_key。这个 openid 是微信为该用户在您的小程序中分配的唯一标识,它并非用户的真实姓名、手机号等敏感个人信息,而是一个用于区分用户身份的匿名化“系统级”标识。

因此,静默授权所获取的“系统用户信息”,并非用户的隐私数据,而是微信为帮助小程序识别不同用户而提供的一项基础服务。它依托于微信强大的用户体系和安全的授权机制,确保了在不干扰用户的情况下,小程序依然能够提供个性化服务。

静默授权的“幕后操作”流程

那么,这“无感”的魔法是怎么实现的呢?其实,它背后是一系列严谨的API调用和数据交换。

流程解析:

  1. 用户打开小程序:一切的开始。
  2. wx.login():小程序前端“悄悄”地调用这个API。它不会弹出任何界面,只会向微信服务器发起一个请求。
  3. 获取 code:微信服务器收到请求后,会返回一个临时的登录凭证 code 给小程序。这个 code 是一次性的,有效期很短(通常是5分钟)。
  4. code 发送至后端:小程序拿到 code 后,会把它发送到你的开发者服务器(也就是你的后端)。
  5. 后端调用 auth.code2Session:这是关键一步!你的后端服务器会拿着从前端传过来的 code,以及你的小程序 AppID 和 AppSecret(这个 AppSecret 是小程序的“钥匙”,千万不能泄露到前端!),去调用微信的 auth.code2Session 接口。
  6. 微信服务器返回 openid 等信息:微信服务器验证通过后,会返回三个重要的信息:
    • openid:用户在当前小程序的唯一标识。
    • session_key:会话密钥,用于后续解密用户敏感数据(比如手机号)的关键。它也是一次性的,且有有效期。
    • unionid (可选):如果你的小程序关联了微信开放平台,并且用户在你的其他应用(如公众号、App)中也授权过,那么微信还会返回 unionid。unionid 是用户在同一开放平台账号下所有应用中的唯一标识,可以帮助你打通用户数据。
  7. 后端处理:你的后端服务器拿到这些信息后,就可以进行用户身份识别、创建或更新用户记录、生成自定义登录态(比如JWT Token)等操作,并把这个自定义登录态返回给小程序。
  8. 小程序完成静默登录:小程序拿到自定义登录态后,就可以在后续的请求中携带这个登录态,后端就能识别用户了。

你看,整个过程用户完全无感,但你的小程序已经成功地“认识”了这位用户。是不是很神奇?

手机号授权:解锁更多姿势的“钥匙”

静默授权虽然好,但它只能获取 openid,如果你需要用户的真实手机号来完成注册、绑定、验证等操作,那就得请出我们的另一位“大侠”——手机号授权了!

为什么需要手机号授权?

想象一下,你要做个外卖小程序,用户下单总得留个电话吧?或者你要做个社交小程序,需要通过手机号来查找好友?这时候,openid 就不够用了,你得获取用户的真实手机号。

手机号授权的“用户体验”

与静默授权不同,手机号授权是显式的。这意味着,用户必须主动点击一个按钮,并且在弹出的授权框中明确同意,你才能拿到他们的手机号。这是微信出于保护用户隐私的强制要求。

手机号授权的流程

既然是“光明磊落”,那它的流程也相对清晰明了。

流程解析:

  • 用户点击按钮: 在你的小程序页面中,需要放置一个 <button> 组件,并设置其 open-type="getPhoneNumber" 属性。这是微信小程序专门为获取手机号提供的能力。

  • 触发 bindgetphonenumber 事件: 当用户点击这个按钮时,小程序会触发 bindgetphonenumber 事件。

  • 用户授权弹窗: 此时,微信会弹出一个标准的授权提示框,询问用户是否同意授权你的小程序获取其手机号。

  • 用户“允许” : 如果用户点击“允许”,bindgetphonenumber 事件的回调函数中会返回一个动态令牌 code(通过 e.detail.code 获取)。

    • 请注意:在这种新方式下,小程序前端不会直接获取到加密的 encryptedDataiv。微信直接提供了一个用于后端调用的 code
  • 发送动态令牌 code 至开发者服务器: 小程序前端需要将这个动态令牌 code 发送给你的开发者服务器。

  • 开发者服务器调用微信接口: 开发者服务器收到 code 后,需要调用微信官方提供的 phonenumber.getPhoneNumber 接口,并将 code 作为参数传入。

    • 每个 code 的有效期为5分钟,且只能使用一次。
  • 微信服务器返回手机号: 微信服务器收到请求并验证 code 后,会将用户的真实手机号返回给开发者服务器。

  • 开发者服务器处理手机号: 开发者服务器在获取到手机号后,可以进行存储、关联用户账号、完成注册或绑定等业务逻辑。

  • 开发者服务器返回结果给小程序: 开发者服务器处理完毕后,将相应的业务结果返回给小程序前端。

  • 用户“拒绝” : 如果用户在授权弹窗中点击了“拒绝”,bindgetphonenumber 事件的回调函数会返回错误信息(例如 e.detail.errMsge.detail.errno),你需要在前端进行相应的提示或处理。

静默授权与手机号授权的“联姻”:从“游客”到“VIP”

前面我们讲了静默授权和手机号授权各自的流程,但它们在实际业务中往往是“夫唱妇随”,共同完成用户身份的识别和打通。理解它们如何“联姻”,才能真正构建一个完善的用户体系。

“联姻”流程解析:

该流程详细描述了用户在小程序中从静默登录到手机号授权,再到后续访问的完整生命周期。

  1. 静默授权,初识身份: 当用户首次打开小程序时,我们首先进行静默授权。小程序调用 wx.login() 获取临时登录凭证 code,并发送给开发者服务器。开发者服务器再用 code 调用微信的 auth.code2Session 接口,获取到用户的 openidsession_keyunionid(如果已绑定开放平台)。

  2. 后端查询,区分“游客”与“熟客” : 你的后端服务器会根据这个 openid 去查询系统用户表。

    • 如果是新用户(openid 未关联) :可以为他创建一个“游客账号”。这个账号主要基于 openid,可以进行一些不需要手机号的功能,比如浏览商品、查看文章等。此时,用户在你的系统里是“无名氏”,但小程序能区分他是谁。
    • 如果是老用户(openid 已关联) :恭喜你,直接识别出他是你的系统用户了!后端返回对应的自定义登录态给小程序。
  3. 手机号授权,晋升“VIP” : 当用户需要进行注册、下单、绑定等需要手机号的功能时,才引导他们进行手机号授权。用户点击带有 open-type="getPhoneNumber" 的按钮并同意授权后,小程序会通过 bindgetphonenumber 事件回调,获取到一个动态令牌 code

  4. 后端调用接口,获取真身: 小程序前端将这个动态令牌 code 发送给开发者服务器。开发者服务器收到 code 后,会直接调用微信后台提供的 phonenumber.getPhoneNumber 接口,并将该 code 作为参数传入。微信服务器验证 code 后,会将用户的真实手机号返回给开发者服务器。

  5. 后端处理,完成关联: 开发者服务器在获取到手机号后,会再次查询系统用户表。

    • 如果手机号是新号:说明这个用户是首次通过小程序完整注册,后端会创建一个新的系统用户,并将这个用户的用户ID、手机号和之前获取到的 openid 进行强关联
    • 如果手机号已存在(例如通过 H5 或 App 注册的) :此时,后端会将这个已有的系统用户(只有用户ID和手机号)与当前小程序的 openid 进行关联。这样,无论用户从 H5、App 还是小程序登录,都能识别为同一个用户。
  6. 后续静默登录,费用“躺平” : 一旦 openid 与系统用户成功关联,用户后续再次打开小程序时,只需要通过静默授权获取 openid。你的后端就能直接通过 openid 查找到对应的系统用户,无需再次进行手机号授权。这样,既提升了用户体验,又节省了手机号授权的费用

静默授权的“甜蜜烦恼”与“注意事项”

静默授权虽然方便又省钱,但它也不是“万能药”,在使用过程中,你可能会遇到一些“甜蜜的烦恼”和需要注意的事项:

  1. 无法做“退出登录”
    • 问题:由于 wx.login() 是微信底层提供的能力,只要用户不主动删除小程序或者清除微信缓存,小程序每次启动时都会自动进行静默授权并获取 openid。这意味着,如果你在前端做了“退出登录”按钮,用户点击后,下次再进入小程序,仍然会通过静默授权重新获取 openid,并可能自动登录。这会让用户感觉“退出登录”功能无效。
    • 应对
      • 前端清除登录态:在用户点击“退出登录”时,前端应清除本地存储的自定义登录态(如 Token),并清除用户相关缓存数据。
      • 后端失效登录态:后端也应该将对应用户的自定义登录态设为失效。
      • 引导用户理解:可以向用户解释,小程序的设计机制使得“完全退出”比较困难,但他们的个人信息在退出后不会被小程序继续使用。
      • 不提供“退出登录”:对于一些不需要严格登录状态的小程序,甚至可以考虑不提供“退出登录”功能,只提供“切换账号”或“解绑”功能。
  2. openid 仅限当前小程序:openid 是用户在当前小程序的唯一标识。如果你的公司有多个小程序,同一个用户在不同小程序中的 openid 是不一样的。如果你需要打通多个小程序的用户数据,就需要使用 unionid。
  3. session_key 的时效性:静默授权获取的 session_key 用于解密敏感数据,它有有效期。因此,后端需要妥善管理 session_key,并在需要时及时更新,避免解密失败。
  4. 网络请求依赖:静默授权的整个流程涉及到小程序前端、开发者后端和微信服务器之间的多次网络请求。任何一个环节的网络问题都可能导致授权失败。因此,需要做好网络异常处理和重试机制。

总结:授权不易,且用且珍惜!

好了,经过一番“鞭辟入里”的讲解,相信大家对小程序静默授权和手机号授权的原理、流程以及它们在构建用户体系中的“联姻”关系都有了更深入的了解。

记住,授权是小程序与用户建立信任的第一步。无论是“无感”的静默授权,还是“显式”的手机号授权,我们都应该:

  • 尊重用户隐私:只获取必要的权限。
  • 提供良好体验:授权流程清晰,拒绝后有友好提示。
  • 保障数据安全:AppSecret、session_key 等敏感信息务必在后端妥善保管。
  • 合理利用 openid:作为用户识别的基础,并与系统用户 ID 关联。
  • 谨慎使用手机号:在必要时才引导授权,并关注成本。

希望这篇文章能帮助大家在小程序的开发道路上少踩几个坑,多写几行“优雅”的代码!下次再遇到授权问题,你就可以拍着胸脯说:“小意思,我可是看过那篇‘幽默风趣’的文章的!”

如果大家在实际开发中遇到任何具体问题,或者有更“刁钻”的业务需求,欢迎在评论区留言讨论,我们可以共同探讨解决方案。

下次再见!👋