背景
我们发现大部分小程序都会使用 wx.getUserInfo
接口,来获取用户信息。原本设计这个接口时,我们希望开发者在真正需要用户信息的情况下才去调取这个接口,但很多开发者会直接调用这个接口,导致用户在使用小程序的时候产生困扰,归结起来有几点:
开发者在小程序首页直接调用
wx.getUserInfo
进行授权,弹框获取用户信息,会使得一部分用户点击“拒绝”按钮。在开发者没有处理用户拒绝弹框的情况下,用户必须授权头像昵称等信息才能继续使用小程序,会导致某些用户放弃使用该小程序。
用户没有很好的方式重新授权,尽管我们增加了
设置
页面,可以让用户选择重新授权,但很多用户并不知道可以这么操作。
此外,我们发现开发者默认将 wx.login
和 wx.getUserInfo
绑定使用,这个是由于我们一开始的设计缺陷和实例代码导致的(wx.getUserInfo
必须通过 wx.login
在后台生成 session_key
后才能调用)。同时,我们收到开发者的反馈,希望用户进入小程序首页便能获取到用户的 unionId
,以便识别到用户是否以前关注了同主体公众号或使用过同主体的App 。
为了解决以上问题,针对获取用户信息我们更新了三个能力:
1.使用组件来获取用户信息
2.若用户满足一定条件,则可以用wx.login
获取到的code
直接换到unionId
3.wx.getUserInfo
不需要依赖 wx.login
就能调用得到数据
获取用户信息组件介绍
组件变化:
open-type
属性增加getUserInfo
:用户点击时候会触发bindgetuserinfo
事件。新增事件
bindgetuserinfo
:当open-type
为getUserInfo
时,用户点击会触发。可以从事件返回参数的detail
字段中获取到和wx.getUserInfo
返回参数相同的数据。
示例:
<button open-type="getUserInfo" bindgetuserinfo="userInfoHandler"> Click me button>
和 wx.getUserInfo
不同之处在于:
1.API wx.getUserInfo
只会弹一次框,用户拒绝授权之后,再次调用将不会弹框;
2.组件 由于是用户主动触发,不受弹框次数限制,只要用户没有授权,都会再次弹框。
通过获取用户信息的组件,就可以解决用户再次授权的问题。
直接获取unionId
开发者申请 userinfo
授权主要为了获取 unionid
,我们鼓励开发者在不骚扰用户的情况下合理获得unionid
,而仅在必要时才向用户弹窗申请使用昵称头像。为此,凡使用“获取用户信息组件”获取用户昵称头像的小程序,在满足以下全部条件时,将可以静默获得 unionid
:
1.在微信开放平台下存在同主体的App、公众号、小程序。
2.用户关注了某个相同主体公众号,或曾经在某个相同主体App、公众号上进行过微信登录授权。
这样可让其他同主体的App、公众号、小程序的开发者快速获得已有用户的数据。
不依赖登录的用户信息获取
某些工具类的轻量小程序不需要登录行为,但是也想获取用户信息,那么就可以在 wx.getUserInfo
的时候加一个参数 withCredentials: false
直接获取到用户信息,可以少一次网络请求。
这样可以在不给用户弹窗授权的情况下直接展示用户的信息。
最佳实践
1.调用 wx.login
获取 code
,然后从微信后端换取到 session_key
,用于解密 getUserInfo
返回的敏感数据。
2.使用 wx.getSetting
获取用户的授权情况
1) 如果用户已经授权,直接调用 API wx.getUserInfo
获取用户最新的信息;
2) 用户未授权,在界面中显示一个按钮提示用户登入,当用户点击并授权后就获取到用户的最新信息。
3.获取到用户数据后可以进行展示或者发送给自己的后端。
One More Thing
除了获取用户方案介绍之外,再聊一聊很多初次接触微信小程序的开发者所不容易理解的一些概念:
1.关于OpenId和UnionId
OpenId
是一个用户对于一个小程序/公众号的标识,开发者可以通过这个标识识别出用户。
UnionId
是一个用户对于同主体微信小程序/公众号/APP的标识,开发者需要在微信开放平台下绑定相同账号的主体。开发者可通过UnionId
,实现多个小程序、公众号、甚至APP 之间的数据互通了。
同一个用户的这两个 ID 对于同一个小程序来说是永久不变的,就算用户删了小程序,下次用户进入小程序,开发者依旧可以通过后台的记录标识出来。
2.关于 getUserInfo 和 login
很多开发者会把 login
和 getUserInfo
捆绑调用当成登录使用,其实 login
已经可以完成登录,getUserInfo
只是获取额外的用户信息。
在 login
获取到 code
后,会发送到开发者后端,开发者后端通过接口去微信后端换取到 openid
和sessionKey
(现在会将 unionid
也一并返回)后,把自定义登录态 3rd_session
返回给前端,就已经完成登录行为了。而 login
行为是静默,不必授权的,用户不会察觉。
getUserInfo
只是为了提供更优质的服务而存在,比如展示头像昵称,判断性别,开发者可通过 unionId
和其他公众号上已有的用户画像结合来提供历史数据。因此开发者不必在用户刚刚进入小程序的时候就强制要求授权。
可以在官方的文档中看到 login
的最佳实践:
Q & A
Q1: 为什么 login 的时候不直接返回 openid,而是要用这么复杂的方式来经过后台好几层处理之后才能拿到?
A: 为了防止坏人在网络链路上做手脚,所以小程序端请求开发者服务器的的请求都需要二次验证才是可信的。因为我们采取了小程序端只给 code
,由服务器端拿着 code
和 AppSecrect
去微信服务器请求的方式,才会给到开发者对应的openId
和用于加解密的 session_key。
Q2: 既然用户的openId
是永远不变的,那么开发者可以使用openId
作为用户的登录态么?
A: 不行,这是非常危险的行为。因为 openId
是不变的,如果有坏人拿着别人的 openId
来进行请求,那么就会出现冒充的情况。所以我们建议开发者可以自己在后台生成一个拥有有效期的 第三方session
来做登录态,用户每隔一段时间都需要进行更新以保障数据的安全性。
Q3: 是不是用户每次打开小程序都需要重新login
?
A: 不必,可以将登录态存入storage
中,用户再次登录就可以拿storage
里的登录态做正常的业务请求,只有当登录态过期了之后才需要重新login
。这样子做一则可以减少用户等待时间,二则可以减少网络带宽。
目前微信的session_key
有效期是三天,所以建议开发者设置的登录态有效期要小于这个值。
别急啊 接下来改的就可能是网络请求的api了 所有程序全部下架 重新修改审核也说不定呢
我们以前做的好多小程序,新用户都无法登录了,全部要重新提交发布,坑爹啊,40多个小程序,登录全部要改,把全部要重新提审,以前都写好的逻辑,这不是折腾人吗?
这个改动很让人难受
这样可以在不给用户弹窗授权的情况下直接展示用户的信息。
这里写错了,只要获取用户信息都会出现授权弹窗
何况按钮这个东西,很难做么,我们自己也可以弄一个按钮绑定个函数,现在把函数退化成按钮这个事情本身,并不会改善这个问题。不认真的开发者依然会出现用户体验不好的问题,认真的开发者,怎么都不会出现这个问题。现在小程序质量整体那么差,你们自己去搜搜看,像样的有几个,残缺的,数据获取不了的,卡顿的,80%以上都不行(你们自己随便搜几个,小公司做的都目不忍视),你们弄个这个能改善那些问题么,你不去规范80%的小程序,解决80%的问题,你们现在弄个这个,不仅把那20%的优秀小程序开发者搞得需要重构,还对那80%的基本没有任何改善。我认为这是闭门造车,不是尊重和倾听我们的广大开发者的声音。这是弄巧成拙。我觉得微信应该以这样的心态来做事情:“如果微信没有如此巨大的流量优势,你们技术部门还敢不敢如此不尊重开发者”?
修改这个底层的API,对开发者这的是伤害很大啊,哎,本身的路程就已经很复杂,很不容易走通,现在说废弃就废弃,哎,桑心啊,难道就不能有一个更好的解决办法吧,做一个按钮,还是要弹窗授权,用户第一次进来,页面是一个按钮,这样的体验难道就更好吗?
这么重要的修改,居然没推文通知。。。我也是醉了
你们是怎么考虑的,这么大刀阔斧的改,有考虑过码农的感受吗?
应该多数开发者都是通过get userinfo 去获取uinonid的。
因为通过openid获取unionid的条件太苛刻了。
如果用户先使用小程序,再去关注公众号,那么小程序里的所有行为都是没有unionid的,用户关注公众号之后,开发者也无法获知该用户在小程序中的行为。比如对于商城来说用户的订单,售后请求等等。
所以,应该是只要小程序的帐号主体下有公众号或者其他应用,就直接返回unionid。
真的是描述不清楚,为原公告补充下述加粗内容:
为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版在未授权userInfo的前提下调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败;如果已经通过wx.authoriz接口对userInfo进行了授权,该接口可正常使用。
这样调整公告和最佳实践之间就没逻辑矛盾了,总结一句话:这个接口去掉弹出授权框功能,需要获取userInfo授权才可以正常使用该接口