- (4)获取用户信息
背景 我们发现大部分小程序都会使用 [代码]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[代码] 有效期是三天,所以建议开发者设置的登录态有效期要小于这个值。
2018-08-17 - (6)微信登录能力优化
小程序和小游戏内的用户登录,我们推荐使用以下两种方式获取用户信息: ▷ 按钮组件的登录方式,用户主动点击按钮可以拉起用户授权弹框,获取用户头像、昵称等信息; ▷ 在不获取用户信息的情况下,可展示用户头像昵称。 用户在没有任何操作的情况直接弹出授权的登录方式将逐渐不再支持,受影响的有 wx.getUserInfo 接口,以及 wx.authorize 接口传入 scope="scope.userInfo" 的情况。 1 为什么平台要做接口调整? 我们提供了 wx.login 和 wx.getUserInfo 接口,用于获取用户的 openID 和基本信息。 推出这两个接口的初衷是希望:当用户使用小程序时,只有访问到真正需要登录的页面,才需要授权并登录。 但在实际应用中,我们发现很多开发者在打开小程序时直接弹出授权框,如果用户点击拒绝授权,无法使用小程序。 在没有任何提示和背景的情况下,直接弹框想要获得用户信息授权,用户脑子里可能会闪过几个哲学问题: 你是谁? 我在哪里? 我为什么要同意? …… 相当一部分用户下意识会点击“拒绝“授权——这样不合理的登录流程既造成了用户的困扰,还使得用户流失。 用户通过小程序可以快速获取服务,因此在访问小程序的第一个页面非常重要。 对于一个互联网产品而言,第一个页面决定了用户对这个产品的认知,用户会选择是否继续使用这个产品。 一个优秀的互联网产品,能够给用户留下一个好的第一印象,用户可以快速了解你的产品,接收到你想要传递的服务信息,从而产生相应的操作行为。 一个优秀的小程序会吸引用户在小程序里进行探索,完成你期望他们去做的事,比如会员注册、商品购买等。 试想一下如果一个品牌的商品官网,一进入要求用户登录才能查看产品信息是什么感觉呢? 因此良好的用户登录体验非常重要。 2 如何设计登录流程? 用户打开小程序时,看第一眼的时候,开发者需要专注以下两个目标: ▷ 精准快速地传达产品理念,开发者要让用户能够快速了解自己的产品和服务; ▷ 将用户流量进行转化,让用户能方便操作或者交易。 一般而言,用户打开小程序后看到的第一个页面,先不要直接弹出授权框,第一个页面可以包含以下内容: ▷ 展示你的小程序功能(如产品、服务、活动等) ,让用户清晰地知道小程序是做什么用的,这些内容可以是你的精选内容; ▷ 激发用户的探索欲,通过描述或者图片吸引用户注意力; ▷ 按照自己的产品目标,给用户提供清晰明确的下一步操作(查看详情、购买等)。 如果某些特殊小程序在使用前一定需要用户登录,或者已经进行到需要用户登录的操作时,可以将 button 组件(其中 open-type 属性指定为 getUserInfo)放置到页面中,页面上可以大致说明以下要点: 为什么需要我授权? 需要我什么信息? 授权后我得到什么好处呢? 接下来在页面上放置一个明显的登录按钮, 建议这个页面上不要有额外的点击区域,以免分散用户注意力,让用户专注于登录这件事情。 3 简单的开发建议 1 当用户打开小程序时访问第一个页面时,先通过 wx.login,获取用户 openID 。这时无需弹框授权,开发者拿到 openID 可以建立自身的帐号 ID。 2 在第一步中,拿到 openID 后,判断是新用户还是老用户。如果是老用户,可以直接登录;如果是新用户,可先在小程序首页展示你的信息服务,让用户对这个小程序有大概的了解,再引导用户进行下一步的操作。 3 当需要获取用户头像昵称的时候,对用户展示一个登录页面,这个页面只有一个最重要的操作,引导用户进行登录。 小程序中,在页面中加入一个 button 按钮,并将 open-type 属性设置为 getUserInfo 。 以小程序为例: 微信登录 对于功能较简单的小程序或者小游戏而言,如果不是必须要获得用户的头像昵称,建议可先通过wx.login 拿到 openID 后,使用 open-data 方式或者开放数据域的方式展示用户信息,整个过程都无需用户授权。 Tips: 1、在用户登录后,开发者需要存储用户的 unionID,而且建议只把 unionID 作为互通的用户标识,不要直接使用 unionID 作为用户 ID。因为一旦小程序迁移到其他的开放平台下,unionID 是会改变的,而 openID 是不变的。 2、用 button 组件的方式获得用户授权后,调用 wx.getUserInfo 就可以直接获取用户信息。这个的意义在于获取过一次之后,用户有可能改昵称头像,因此为了及时同步,最好是定期获取用户信息。 这里两个小提示: ▷ 定期使用 wx.getUserInfo 获取并更新用户的信息; ▷ 如果用户授权过一次之后,又在设置中关掉了授权(或者本地删除了小程序),那这时再调用 wx.getUserInfo 也是不会成功的,需要重新获得授权。 相关开发文档参考: ▷ 小程序 1、小程序 wx.login 2、button 组件,并将 open-type 指定为 getUserInfo 类型,获取用户基本信息 3、open-data 展示用户基本信息 ▷ 小游戏 1、小游戏 wx.login 2、用户信息按钮 UserInfoButton 3、开放数据域下的展示用户信息
2018-08-17