# 开发 \| 拒绝打开就授权！小程序如何用新能力获取用户资料？

- 作者：Astrian
- 发布时间：2017-08-01 20:00
- 原文：https://www.ifanr.com/minapp/882331

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-dev-final-feature.jpg)

前几天，微信官方突然宣布，小程序将使用[新的用户数据获取的方式](http://www.ifanr.com/minapp/880357)。

简单来说，**这次能力更新，为 `button` 组件的 `open-type` 属性赋予了新的有效值 `getUserInfo`（声明需要获取用户信息）**。

同时，官方还宣布，**如果提审的小程序出现「启动即要求授权」和「强制要求授权」的情况，将会无法通过审核**。

那么，开发者应该如何适配新推出的获取用户资料方式呢？在新方式下，还需要注意一些什么呢？

知晓程序（微信号 zxcx0101）今天就来为你讲解，如何使用新方法获取用户资料。

关注「知晓程序」微信公众号，在后台回复「0109」，一张图教你玩转小程序。

### 如何使用新方法获取用户资料？

我们以「[虚荣数据库](http://www.ifanr.com/minapp/812943)」小程序为例，来展示如何将旧的登录模式升级到新的模式。

在旧版的「虚荣数据库」中，小程序调用获取用户数据模式是这样的：**处理登录、获取用户数据和注销行为的方法存储于小程序实例（`app.js`）中**，便于实际页面调用。

大致步骤是这样的：

1. 当小程序需要调取用户资料时，用户通过点击相应元素（不一定是按钮），触发事件；
2. 相应页面实例收到点击事件后，调用小程序实例中的登录方法，进行资料读取；
3. 小程序实例调用微信接口，获取用户资料；
4. 成功获取资料，调用页面实例传入的回调函数；
5. 页面实例通过回调函数，得知接口调用状态和用户资料，进行后续任务。

简单的代码如下：

```
<!-- page.wxml -->
<view class='list-item' bindtap='login'>点击登录</view>
```

```
// page.js

var app = getApp()

Page({
  login(){
    sync(function* (api) {
      var res = yield app.login(api.next) // 使用了框架，将 (err, result) 中的 result 传入 res，同时保持同步性。
      if (api.err) return console.log('login function has error') // 如果登录方法出错则报错
      // 登录完毕后，调用用户数据等信息，使用 that.setData 写入
    })
  }
})
```

```
// app.js

App({
  login(callback){
    wx.login({ // 获取用户资料前，此步骤必需
      success: function (res) {
        if (res.code) {
          var logincode = res.code // 获取匿名识别符，用来鉴别同一用户
          wx.getUserInfo({
            success: function (res) {
              wx.request({})// 将用户匿名识别符、资料发送至服务器
              callback(null, res) // 将成功获取用户资料的提示发送回页面实例
            },
            fail: function () {
              wx.showModal({}) // 当拒绝授权的时候，提示用户需要开启权限，确认时调用微信的权限管理界面
              callback('fail to modify scope', null)
            }
          })
        } else {
          callback('fail to call wx.login()', null)
        }
      }
    });
  }
})
```

在新的方式中，**获取用户数据的实体，从 `wx.getUserInfo()` 函数，变成了按钮上的事件函数**。

使用新的方式获取用户信息，过程大致如下：

1. 当用户点击绑定有页面实例获取用户数据方法的按钮后，微信向用户确认授权；
2. 授权完成，微信调用按钮上绑定的方法，同时传入用户数据；
3. 页面实例调用 `app.js` 中的登录函数，同时额外传入用户数据。

之后的事情，一切照旧。

厘清了新旧方法之间的差异，代码的修改思路就比较清晰了。

首先，我们**将触发登录事件的元素，统一改为 `button` 元素**，还要加上 `open-type='getUserInfo'` 参数。

同时，我们还要加入 `bindgetuserinfo` 参数，并在其中填入加入获取用户数据的页面实例方法。

```
<!-- page.js -->
<button class='hiddenbtn' bindgetuserinfo='login' open-type='getUserInfo'>点击登录</button>
```

然后，**我们在相应事件中，将用户数据传入小程序实例的 `login()` 方法**。

```
// page.js

var app = getApp()

Page({
  login(userinfo){ // 需要一个参数来额外接收用户数据
    app.login(userinfo, (err, res) => { // 呃…… 框架死掉了 🤣 只能屈服于回调地狱
      if (err) return console.log('login function has error') // 如果登录方法出错则报错
      // 登录完毕后，调用用户数据等信息，使用 that.setData 写入
    })
  }
})
```

接下来，只需要让 `app.js` 按新的方法处理用户数据，就可以了。

```
login(userinfo, callback) {
  wx.login({}) // 现在，调用 wx.login 是一个可选项了。只有当你需要使用微信登录鉴别用户，才需要用到它，用来获取用户的匿名识别符
  if (userinfo.detail.errMsg == 'getUserInfo:ok') {
    wx.request({}) // 将用户信息、匿名识别符发送给服务器，调用成功时执行 callback(null, res)
  }
  else if (userinfo.detail.errMsg == 'getUserInfo:fail auth deny') { // 当用户点击拒绝时
    wx.showModal({}) // 提示用户，需要授权才能登录
    callback('fail to modify scope', null)
  }
}
```

现在，来跑一下小程序——嗯，一切正常。

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-get-user-profile.jpg)

### 如何向下兼容旧版微信？

想必很多人在使用新方法的时候，都会担心旧版微信的兼容问题。

的确，**这种登录方法在版本太老旧的微信上，是无法正常完成的**。

不过不用担心，**我们可以使用微信提供的 `wx.canIUse()` 方法，来做到接口兼容性核查**，在旧版微信上引导用户更新，或是选择使用旧方式获取用户信息。

我们先在按钮上，**用 `bindtap` 来额外绑定一个兼容性检查事件**：

```
<!-- page.wxml -->
<button class='hiddenbtn' bindgetuserinfo='login' open-type='getUserInfo' bindtap='canILogin'>点击登录</button>
```

然后，我们在相应的函数中，进行兼容性检查：

```
// page.js

Page({
  canILogin(){
    if(!wx.canIUse('button.open-type.getUserInfo')){ // 对应的功能就是通过按钮获取用户资料
      wx.showModal({}) // 向用户提示需要升级微信
    }
  }
})
```

在开发者工具中，将「基础库版本」调低，再次运行，可以看到小程序成功做出了判断。

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-old-wechat-cannot-get-profile.jpg)

在本例中，我们选择提示、引导用户更新微信；你也可以选择调用 `wx.getUserInfo()` 接口，直接获取用户资料。

想看完整的代码示例？关注微信公众号「知晓程序」，回复「源码」，即可获得利用新方式获取用户资料的源码 Demo。

### 还需要注意什么问题？

如果小程序需要判断不同用户，但不需要获取额外用户资料，只需在小程序调用 `wx.login()` 接口，再用自己的服务器调用微信的接口，即可获取用户的 OpenID，无需用户额外授权。

在新方式下，**若用户首次拒绝授权，可以通过再次点击按钮重新请求授权**。开发者只需提示用户需要授权即可，无需调用小程序权限开关界面，要求用户手动打开授权开关。

另外，转换到新方式时，**可以将相应视觉元素用 `button` 打包，并为相应 `button` 设定无背景色、无边框等属性**，达到隐藏触发按钮的目的，减少对界面的改动。

当然，如果你的小程序是刚启动就会要求用户授权的，那么你应该尽快修改小程序，使用新的按钮回调方式，获取用户的资料。

微信官方已经提示开发者，不应在刚启动小程序时直接向用户授权获取用户资料，小程序也不应该强制让用户授权小程序访问用户资料。否则，小程序将不予通过审核。

**关注「知晓程序」公众号，在微信后台回复「开发」，获取小程序开发精选文章。**

![zxcx&#95;0208](https://s3.ifanr.com/wp-content/uploads/2017/02/zxcx_0208.png)
