背景
小程序一个比较重要的能力就是获取用户信息,也就是使用 wx.getUserInfo
接口。我们发现几乎所有的小程序都会调用这个接口。虽然我们在设计文档上有提出最好的设计是在真正要用户信息的情况下才去获取用户信息,不过很多开发者并没有按照我们的期望去做,导致用户在使用的时候有很多困扰。
归结起来有几点:
开发者在首页直接调用
wx.getUserInfo
进行授权,弹框有会使得一部分用户放弃小程序的使用。开发者没有处理用户拒绝弹框的情况,有部分小程序强制要求用户授权头像昵称等信息才能继续使用小程序。
用户没有很好的方式重新授权,虽然在前几个版本我们增加了
设置
页面可以让用户选择重新授权,但是操作还是不够便捷。开发者希望进到首页就获取到用户的
unionId
,以便和之前已经关注了公众号的用户画像关联起来。开发者默认将
wx.login
和wx.getUserInfo
绑定使用,这个是由于我们一开始的设计缺陷和实例代码导致:getUserInfo
必须通过wx.login
在后台生成session_key
后才能调用。
为了解决以上几点,我们更新了三个能力:
使用组件来获取用户信息,用户拒绝授权后也可以重新弹窗再次授权
若用户满足一定条件(下文有详细介绍),则可以用
wx.login
获取到的code直接换到unionId
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
不同之处在于:
API
wx.getUserInfo
只会弹一次框,用户拒绝授权之后,再次调用将不会弹框组件
由于是用户主动触发,不受弹框次数限制,只要用户没有授权,都会再次弹框
直接获取unionId
考虑很多场景下,业务方申请userinfo授权主要为了获取unionid。我们鼓励开发者在不骚扰用户的情况下合理获得unionid,而仅在必要时才向用户弹窗申请使用昵称头像。为此,凡使用“获取用户信息组件”获取用户昵称头像的小程序,在满足以下全部条件时,将可以静默获得unionid。
在微信开放平台下存在同主体的App、公众号、小程序。
用户关注了某个相同主体公众号,或曾经在某个相同主体App、公众号上进行过微信登录授权。
getUserInfo 和 login
很多开发者会把login和getUserInfo捆绑调用当成登录使用,其实login已经可以完成登录,可以建立账号体系了,getUserInfo只是获取额外的用户信息。
在login获取到code,然后发送到开发者后端,开发者后端再通过接口去微信后端换取到openid和sessionKey(并且现在会将unionid也一并返回)之后,然后把3rd_session返回给前端,就已经完成登录行为。而login行为是静默,不必授权的,不会对用户造成骚扰。
getUserInfo只是为了提供更优质的服务而存在,比如展示头像昵称,判断性别,通过unionId和其他公众号上已有的用户画像结合起来提供历史数据。所以不必在刚刚进入小程序的时候就强制要求授权。
推荐使用方法
调用
wx.login
获取code
,然后从微信后端换取到sessionKey
,用于解密getUserInfo
返回的敏感数据。使用
wx.getSetting
获取用户的授权情况如果用户已经授权,直接调用 API
wx.getUserInfo
获取用户最新的信息用户未授权,在界面中显示一个按钮提示用户登入,当用户点击并授权后就获取到用户的最新信息。
获取到用户数据后可以进行展示或者发送给自己的后端。
文档中的quickStart已经更新
特别注意
为了给用户提供更好的小程序环境,我们约定在一段时间后(具体时间会做通知),若还出现以下情况(包括但不限于),将无法通过审核
初次打开小程序就弹框授权用户信息
未处理用户拒绝授权的情况
强制要求用户授权
已经上线的小程序不会受到影响。
FAQ
Q: 除了 UserInfo 呢,比如说位置信息 --- ’风の诺言 .
A: 其他授权信息不像用户信息那么高频繁,也基本是在使用时候才申请授权,所以没有同 UserInfo 一起给出。我们会先看看 UserInfo 的使用情况再结合具体场景我们会给出相应的方案
Q: 后台要维护用户信息 --- Azleal
我们的小程序业务是功能都需要授权才能使用的(也就是必须拿到unionid获取用户信息) --- elemeNT
我在小程序与服务号的数据需要互通,通过unionId来确定用户的唯一性,如果在用户进入小程序后不强制他授权,单凭一个openid来存储他的用户数据,在用户下次从服务号进入时。不就会产生重复数据吗?就没做到数据互通了 --- ﺭ并向你吐了趴口水ﺭ五年.
另外看到官方提到 要强制推行,我想说我们目前所有用户是通过unionid注册的。那么这些用户就不得不使用 openid重新登录 、注册一遍。更重要的是,之前他们的相关数据都会对应不上(因为你们也不允许强制用户登录授权) --- 羊毛
现在这种方案,不能满足我们的需求,我们的小程序,必须一进入就要获取他的信息,然后加载他的数据; --- 韩文
A: 调用`wx.login`已经可以获取到用户的登录态,已经可以做用户账号的管理。 UserInfo 中带的 UnionId 是额外的信息,没有它完全可以完成登录
对于需要和开发平台绑定的业务进行数据互通的情况,一个新用户进来没有互通数据的情况下也是可以体验到所有业务,那么对于没有授权unionId的用户,可以将其当成是新用户,当真正授权unionId之后再做绑定完全是可以的
Q: 我需要确保用户的唯一性,这样就必须取unionID,否则用户删除了小程序,或者换了设备, 下次再进来这个小程序,该用什么来区分是上次来过的用户呢?? --- WEI+
A: 如果你本身没有其他公众号、App、小程序,那么也就没必要拿到unionid,因为unionid是打通你在开放平台下所有应用的标识
如果只有一个小程序,用 openid 足以, openid 是一个用户对于一个小程序的标识,永远不变
Q: wx.getUserInfo 是网络请求,如果使用了 open-type = "getUserInfo",是否每次点击都会调接口? --- SouthernBox
A: 是的,open-type="getUserInfo" 的作用以及内部实现基本和 wx.getUserInfo 一样
区别是一个开发者主动(拒绝一次不再弹窗),一个是用户主动(拒绝任意次都可以重新弹窗)
Q: 比如有一个创建按钮,用户点击一次授权了,我已经获取到用户信息,再次点击就没必要再调用 getUserInfo 去网络请求了。 --- SouthernBox
A: 可以参考文中 quickStart 的做法,如果已经授权了,那就可以把按钮隐藏,之后的授权直接用API wx.getUserInfo 调用(因为已经授权,所以也不会弹窗),用户也不会再点了
Q: 小程序是不是必须要用微信自带的授权才可以登录 ,能否不使用授权方式登录,用自己系统的api接口数据实现?这个会不会涉及到审核不过的问题??麻烦解答一下 谢谢了。 --- WEI+
A: 自己做登录不会涉及到审核问题。
不过不建议在没有原有账号体系的情况下让用户在小程序内注册,过重的行为会损失用户。
Q: 在小程序中有一个"我的"页面,这是属于会员页,如果用户要进入这个页面就必须授权。交互方式就是在用户未授权情况下整个页面只显示一个授权获取用户信息的button 按钮,这个需要用户自己去触发,算不算强制授权? --- ﺭ并向你吐了趴口水ﺭ五年.
A: 强制授权是说如果用户如果不授权基本信息,连最基础的浏览功能都不提供(当然这个也是要分具体的业务场景,不会限制得太死板)
可以有更好的交互,参考下主流App,在未登录的时候点击【我的】页面,也不会直接要求登录,而是展示了一定的页面结构,同时给一个登录按钮(例如【携程】【京东】等),之后再在这个页面做操作的话可以弹一个登录页面或按钮提示用户登录是完全可以的。
上述所说的登录只是用户感知上的登录,从业务逻辑上用户其实在 wx.login 的时候已经完成登录了。
Q: 看了很多评论,有些人还是不知道为什么官方要这样做,我作为一个商家角度来说下。 --- Mr.J
1. 比如我们要做一些户外推广的二唯码,用户只看到了你的图片宣传单,扫描二唯码一打开就提示“需要获取你的个人信息,您是否允许”,你不要当自己是开发者当自己是一个正常人,看到这个提示我相信很多人的第一反应就是拒绝。如果第一步已经把你拒之门外,谈何营销?
2. 没有小程序之前,我们在公众号有很多用户,都绑定了unionid,有小程序之后我们考虑怎么让用户接受小程序,可以静默登录我觉得非常好,从公众号过来的用户可以直接就登录了,没有任何提示,完美的对接,这是一个很好的体验。
A: 说得很好,我们的这些改造不仅是为了开发者,同时也是为了这个生态下的用户考虑。希望开发者们也能站在用户的角度去思考怎么做一个产品。
Q: 我不明白为什么login 给多个unionid 为什么不行? unionid也不能算是个人信息吧,给多个unionid可以更方便开发者,而且很多情况下就不用调用getUserInfo了 --- candyTong
我们提个建议,能否直接开放unionid呢?这样也许会有许多小程序不需要再弹窗了。既一定程度保障了用户体验,也照顾到了我们开发者的体验。 --- 羊毛
A: 如果直接开放了unionid,就会出现这种情况:当你作为一个用户进入一个小程序,这个小程序并没要求你授权就直接把你的头像昵称显示出来(它之前把unionId对应的头像昵称都存了下来),但是这个小程序主体(open平台主体和公众平台主体并不相同)相关的任何一个应用你从来没用过,你会不会觉得很奇怪并且很不舒服,觉得自己在微信内的用户信息没有丝毫的保障?
Q: 那有推荐的比较好的例子么?对于必须使用用户头像、昵称这些信息的小程序而言 --- 亚里士朱德
A: 首先,没有什么逻辑是一定要使用用户的头像、昵称才能work的。对于这个case,完全可以先用默认头像、匿名昵称先做替代,用户点击默认头像后就可以弹出授权信息,非常的水到渠成。
Q: 之前看了这个帖子一直在思考,如果是一进去需要回去用户的地理位置信息显示到地图上的呢?这样算不算是一进去就弹窗授权获取用户信息? --- 吴俊绩🤔
A: 地图的情况和获取用户信息不同,我们目前还没对地图的授权请求有所调整。当前不受上述策略的影响
Q: 对于开发者而言,小程序与公众号是同级的,只是不同的入口 但是这样的设计,公众号与小程序成了主从关系咯 --- log琥珀①
A: 并无什么主从关系,只是多一个渠道让开发者可以更方便的获取到已经是该主体下用户的unionId
@ 胡浩
比如有一个创建按钮,用户点击一次授权了,我已经获取到用户信息,再次点击就没必要再调用 getUserInfo 去网络请求了。
这样的场景应该比较多。
@胡浩
你好!wx.getUserInfo 是网络请求,如果使用了 open-type = "getUserInfo",是否每次点击都会调接口?
@有龙则灵
这些小程序都需要整改,文中说了,在某个时间后,这类先授权再访问的小程序会不能通过审核
@SouthernBox
之前确实是我们设计得对用户不够友好,所以改成了现在这种方式
唉,真曹丹,我们做健康码的,需要获取用户手机号,身份证,姓名和openid。由于健康码不可能在你微信一个平台上发部,所以我就想尽量做到统一。好家伙,结果小程序不能通过后端直接请求url获取用户名,我都在后端请求并获取access_token、openid和sessionKey了,你还不让我获得用户个人信息,我服了。把那些url,还有依赖的那些方法全都取消掉了。其他的比如支付宝都可以后端获取。。。。。。。。。。。。。。。。
微信解密encryptedData出息 openId乱码 确定是传的encryptedData 反复查看了的
实锤了 发现前端的问题 encryptedData 和sessionKey是捆绑在一起的 只要sessionKey变了 在传之前的encryptedData 就无法解密 作为专业前端对于小程序的理解还不如后台开发人员 这是大家在工作中必须认真反复理解微信登录这个流程 谨记
我想问下用户没有关注过公众号,但是使用过公众号的页面登录授权,这样小程序还是无法通过wx.login取到用户的unionid吗(公众号和小程序已经绑定到开放平台)
你好,如果我想获取当前设备对唯一性,有什么建议吗?