作過、知道、瞭解微信小程序的都知道若是你的小程序應用須要獲取微信的用戶信息數據是須要經過用戶贊成的,也就是須要用戶受權,若是用戶不受權那麼你就拿不到用戶的信息。不少人也都知道如今的人什麼均可以不用帶,但手機不準要帶,由於手機就是咱們的所有,不管是錢包,證件等等。因此安全和隱私就是一個比較敏感的話題了。json
小程序這麼作也是爲了保護用戶的隱私數據,早期開發小程序的都知道,小程序的受權在中途接口時大改了的,當時不少人吐槽,反正改和沒改都是同樣的,作任何事都會有人吐槽的。小程序
在我看來小程序的作法挺好,畢竟用戶的隱私仍是又用戶本身來作決定的,特別最近頭條和騰訊開發數據之間由於頭像等信息的事件,這種就更須要了。微信小程序
今天就來看看如何去作一個小程序的受權封裝,這裏封裝主要針對小程序應用必需要微信用戶數據的,因此也就是不受權就沒辦法用的。api
首先須要咱們在小程序組件目錄中添加一個受權的組件,基本結構以下:安全
而後新建一個頁面用於組件的測試,以下:上面的代碼json和wxml文件中沒有具體展現,你們要記得引入組件以及在wxml中添加組件的標籤,若是不是很清楚能夠看看微信小程序組件的使用。bash
組件的界面主要是想模仿微信小程序自帶受權彈窗的樣式,因此就按照這個樣式作一個,以下:微信
<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 謝謝你們!