微信小程序授权组件封装

2,459 阅读8分钟

做过、知道、了解微信小程序的都知道如果你的小程序应用需要获取微信的用户信息数据是需要通过用户同意的,也就是需要用户授权,如果用户不授权那么你就拿不到用户的信息。很多人也都知道现在的人什么都可以不用带,但手机不许要带,因为手机就是我们的全部,无论是钱包,证件等等。所以安全和隐私就是一个比较敏感的话题了。

小程序这么做也是为了保护用户的隐私数据,早期开发小程序的都知道,小程序的授权在中途接口时大改了的,当时很多人吐槽,反正改和没改都是一样的,做任何事都会有人吐槽的。

在我看来小程序的做法挺好,毕竟用户的隐私还是又用户自己来做决定的,特别最近头条和腾讯开发数据之间因为头像等信息的事件,这种就更需要了。

今天就来看看如何去做一个小程序的授权封装,这里封装主要针对小程序应用必须要微信用户数据的,所以也就是不授权就没办法用的。

结构搭建

首先需要我们在小程序组件目录中添加一个授权的组件,基本结构如下:

然后新建一个页面用于组件的测试,如下:

上面的代码json和wxml文件中没有具体展示,大家要记得引入组件以及在wxml中添加组件的标签,如果不是很清楚可以看看微信小程序组件的使用。

组件的基本结构

组件的界面主要是想模仿微信小程序自带授权弹窗的样式,所以就按照这个样式做一个,如下:

<view class='box' catchtouchmove='true'>
  <view class='pop'>
    <view class='top'>
      <view class='txt'></view>
      <view class='title'>微信授权</view>
      <view class='txt'>关闭</view>
    </view>
    <view class='center'>
      <view class='explain'><text>土家肸哥申请获得以下权限:</text></view>
      <view class='tip'>
        <view class='dian'></view>
        <text>同意此应用访问你的相机功能</text>
      </view>
    </view>
     <button class='bottom' open-type="openSetting">允许</button>
  </view>
</view>

上面的代码有一个地方要注意就是允许这个按钮,由于微信小程序后来接口调整必须要使用按钮才能打开设置界面授权,而且小程序的授权api只在用户第一次授权时才会弹窗询问,如果一旦拒绝授权,那么后来就不能再调起授权弹窗界面了,所以头疼的问题就在这里,明明官方有一个好的弹窗可以用,就是不给用,非要自己去写一个。没办法要用人家的东西,必须得遵守人家的规则,所以只能自己写了。

组件的样式
.box{
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'PingFang SC';
  background-color: rgba(0, 0, 0, .4);
  
}
.box .pop{
  width: 621rpx;
  height: 522rpx;
  border-radius: 10rpx;
  background-color: rgb(248,247,249);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.box .pop .top{
  width: 100%;
  height: 94rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1rpx solid rgb(233,237,245);
}
.box .pop .top .txt{
  font-size: 28rpx;
  color: rgb(136,136,136);
  width: 128rpx;
  height: 93rpx;
  line-height: 93rpx;
  text-align: center;
}
.box .pop .top .title{
  font-size: 36rpx;
  font-weight: bold;
}

.box .pop .center{
  width: 100%;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.box .pop .center .duoduo{
  width: 71rpx;
  height: 71rpx;
  border-radius: 50%;
  margin-bottom: 32rpx;
}
.box .pop .center .duoduo image{
  width: 100%;
  height: 100%;
  border-radius: 50%;
}
.box .pop .center .explain{
  font-size: 32rpx;
  width: 520rpx;
  text-align: center;
  border-bottom: 1rpx solid rgb(233,237,245);
  padding-bottom: 32rpx;
}
.box .pop .center .tip{
  width: 520rpx;
  font-size: 28rpx;
  color: rgb(136,136,136);
  display: flex;
  align-items: center;
  margin-top: 32rpx;
  
}
.box .pop .center .tip .dian{
  width: 9rpx;
  height: 9rpx;
  background-color: rgb(136,136,136);
  border-radius: 50%;
  margin-left: 10rpx;
  margin-right: 22rpx;
}
.box .pop .bottom {
  width: 100%;
  height: 89rpx;
  line-height: 89rpx;
  text-align: center;
  border-top: 1rpx solid rgb(233,237,245);
  font-size: 32rpx;
  color: rgb(66,169,31);
}

有了样式就可以看到长什么样了,效果如下:

弹窗是写好了,我们的逻辑怎么写呢,根据上面提到的规则首先需要使用微信小程序自带的授权api来让用户选择,如果用户拒绝才用自己写的弹窗来提示用户授权,其实这里会有一个问题就是当用户点击拒绝后有弹窗提示用户授权,这就是微信为什么这样改的原因,老是给用户弹窗,所以建议大家在做小程序的时候设计一个游客状态时微信最为提倡的。

组件逻辑

首先的用微信小程序自己的api来获取用户是否已经授权了,代码如下:

/**
     * 检测用户是否已经授权过某个权限,如果没有授权就调用小程序的授权,如果授权了就返回相应的状态给回调函数
     * scope为具体的某个权限
     * cb为回调
     */
    isAuthorize(scope, cb) {
      let self = this;
      wx.getSetting({
        success(res) {
          if (!res.authSetting['scope.' + scope]) {
            wx.authorize({
              scope: 'scope.' + scope,
              success() {
                return typeof cb == "function" && cb();
              },
              fail() {
                self.setAuthTxt(scope);
                self.callBack = cb;
                self.setData({
                  popShow: true
                })
              }
            })
          } else {
            return typeof cb == "function" && cb();
          }
        }
      })
    }

在组件的methods中添加上面的方法,这里主要是用的回调函数来处理授权成功多需要执行的逻辑。上面的代码大家也可以看到如果授权失败则会调用setAuthTxt这个函数,这里主要功能就是设置弹窗的一些提示信息,设置好后将回调保存,最后显示弹窗授。设置页面提示信息很简单就是设置data的值,如下:

setAuthTxt(authType) {
      var authTxt = '';
      switch (authType) {
        case 'userInfo':
          authTxt = '用户信息';
          break;
        case 'userLocation':
          authTxt = '地理位置';
          break;
        case 'record':
          authTxt = '录音功能';
          break;
        case 'writePhotosAlbum':
          authTxt = '保存到相册';
          break;
        case 'camera':
          authTxt = '摄像头';
          break;
      }
      this.setData({
        authType: authType,
        authTxt: authTxt
      })
    }

如果上面的内容没有你需要请求的权限的对应,请自行按照格式添加即可。

这里需要对页面的结构修改一下,主要添加一些事件来处理授权操作,如下:

+ <view class='box' catchtouchmove='true' wx:if='{{popShow}}'>
  <view class='pop'>
    <view class='top'>
      <view class='txt'></view>
      <view class='title'>微信授权</view>
+      <view class='txt' bindtap='popClose'>关闭</view>
    </view>
    <view class='center'>
      <view class='explain'><text>土家肸哥申请获得以下权限:</text></view>
      <view class='tip'>
        <view class='dian'></view>
+        <text>同意此应用访问你的{{authTxt}}功能</text>
      </view>
    </view>
+     <button class='bottom' open-type="openSetting" bindopensetting="getAuthorizeTool">允许</button>
  </view>
</view>

然后就是用户点击允许的逻辑了,如下:

getAuthorizeTool: function(res) {
      var scope = 'scope.' + this.data.authType;
      if (res.detail.authSetting[scope]) {
        this.setData({
          popShow: false
        })
        return typeof this.callBack == "function" && this.callBack();
      }
    }

这里记得最后成功返回保存的回调告诉调用者授权成功了,最后记得添加上关闭弹窗的事件处理函数,如下:

popClose() {
      this.setData({
        popShow: false
      })
    }

到这里这个组件算是封装好了,下面就看看如何使用这个封装好的组件了。

授权组件的使用

组件的使用这里就不做过多介绍,大家可以看看官方文档,主要介绍封装的组件的几种情况。首先需要在json文件中引入组件,然后在wxml中添加组件标签,这里需要注意给标签添加一个id方便后面调用事件,如下:

<!--pages/auth/auth.wxml-->
<text>pages/auth/auth.wxml</text>
<auth id='authorization'></auth>

在调用的要么ready生命周期中获取组件实例,如下:

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    this.authorize = this.selectComponent("#authorization");
  },

最后就是调用了,这里分几种情况调用。

页面级调用

这个其实就是如果某个页面需要某些权限的,当然啦,这个组件目前只是简单的功能所以这种情况即使用户不授权页面也已经加载了,所以适合有游客状态的使用,如果没有游客状态的要么添加一个页面要么自己加以改进。调用方法如下:

  onReady: function () {
    this.authorize = this.selectComponent("#authorization");
    this.authorize.isAuthorize('record', () => {
      console.log('fffffffff')
    })
  },

其实就是在获取到组件实例后调用即可

按钮级调用

这种主要针对点击某个按钮的操作需要获取某个权限才能进行的,如点击按钮录制语音的,方法和上面的一样,只是具体调用的函数在不同地方而已,如下:

onReady: function () {
    this.authorize = this.selectComponent("#authorization");
  },
  /**
   * 处理录制按钮的点击事件
   */
  handleRecordButton(){
    this.authorize.isAuthorize('record', () => {
      console.log('fffffffff')
    })
  },

主要的调用就这两种。

调用效果

调用组件后的效果风三种情况。

只触发小程序自带授权

这种情况就是用户在初次使用时调用的是微信小程序自带的授权弹窗,而且用户马上就是授权了,这种情况的效果如下:

上面的动图中大家可以看到授权之后调试器就会打印出来了,说明授权成功了。

拒绝授权触发自定义弹窗

当用户拒绝授权后就可以弹窗我们自定义的弹窗了,在自定义弹窗中可以选择允许或者不处理。这里主要是自定义弹窗后允许的情况。效果如下:

用户拒绝自定义授权

如果上面异步用户选择了关闭,那么回调就不会执行了,和上面提到的页面级一样了,效果如下:

到此这个授权组件就已经封装查不到了,如果有什么错误或者不足希望大家提出,共同学习,交流! 也可以加我的vx:w_loading 谢谢大家!