收藏
评论

(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 后,会发送到开发者后端,开发者后端通过接口去微信后端换取到 openidsessionKey(现在会将 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 有效期是三天,所以建议开发者设置的登录态有效期要小于这个值。

169794浏览
最后一次编辑于  2018-08-17
知识库内容非实时更新,可能已过期、失效或不适用于当前情形,请谨慎参考
收藏
反馈

89 个评论

  • kindear
    kindear
    2018-11-28

    建议是使用小程序云开发 调用 wx.cloud.callfunction({

    name:'login'

    })

    返回值里可以获得用户的唯一识别码,不要要再去写登录界面了。

    而且不影响其他功能的使用。

    2018-11-28
    赞同
    回复
  • 2018-10-25

    这个获取用户权限改动确实恶心,由于也做pc端的东西,前一段突然发现之前开发的小程序进不去了,提示说是官方移除掉了主动获取用户信息,必须用按钮点击才可以授权,之前的逻辑就是弹出授权后从后台拿登录信息,现在完全没法用了,也懒得改了,项目基本废弃了,要不然有的恶心了。。

    2018-10-25
    赞同
    回复
  • 🇨🇳
    🇨🇳
    2018-06-29

    腾讯这么烂的产品为毛这么多人用!

    2018-06-29
    赞同
    回复
  • 🇨🇳
    🇨🇳
    2018-06-29

    腾讯这么烂的产品为毛这么多人用!

    2018-06-29
    赞同
    回复
  • 🇨🇳
    🇨🇳
    2018-06-29

    腾讯这么烂的产品为毛这么多人用!

    2018-06-29
    赞同
    回复
  • ʚwuspɞ
    ʚwuspɞ
    2018-06-26

    gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg

    2018-06-26
    赞同
    回复
  • Bobo
    Bobo
    2018-06-13

    微信对开发者一点都不友好,这点应该多学学其他平台。

    2018-06-13
    赞同
    回复
  • 同步
    同步
    2018-06-09

    因为请求数据是通过wx.login有登录凭证后才发起网络请求,服务端校验才返回正确的数据给前端小程序的,在开发过程中发现,如果我在app.js没有每次都调用wx.login,那么做了请求返回回调校验,再重新登录,再把之前未请求完毕的数据发起请求。反而觉得首次用户使用小程序上加载数据慢了一点。


    那这个wx.login不用每次进来请求,应该怎么处理更好点?

    2018-06-09
    赞同
    回复
  • 2018-05-30

    凡使用“获取用户信息组件”获取用户昵称头像的小程序,在满足以下全部条件时,将可以静默获得 unionid

    1.在微信开放平台下存在同主体的App、公众号、小程序。

    2.用户关注了某个相同主体公众号,或曾经在某个相同主体App、公众号上进行过微信登录授权。

    刚刚测试了一个新注册的微信号,关注了公众号确实可以获取到unionId


    但是在满足条件1的web页上进行微信授权登录后还是获取不到unionId


    最主要的问题是getUserInfo的弹框选择同意到底算满足这个条件吗?目前测试后台也不能静默获取到unionId


    请看到我,急急急!!!


    为啥不能在同意wx.getUserInfo的button之后通过wx.login()就能直接获取到unionId呢???

    2018-05-30
    赞同
    回复 1
    • 2018-05-30

      @官方

      2018-05-30
      回复
  • 小、坏蛋
    小、坏蛋
    2018-05-17

    你做一个按钮不是还要弹出一个授权框嘛,那用户再点击拒绝咋办?拒绝的判断条件是什么?

    2018-05-17
    赞同
    回复

正在加载...

登录 后发表内容