天天看點

淺談微信小程式授權應用

微信小程式中關乎“授權”的,抛開各路“牛鬼蛇神”不談,大體上也就兩種:

  1. 位置授權
  2. 使用者資訊授權

切記的是:在微信一直打着的“使用者至上”的旗号下,幾乎一切使用者相關的應用都需要使用者手動授權!是以必須要有提示的。

位置授權

昨天完成了微信小程式項目的最後一點内容,裡面我加了個“點選自動定位”的功能,請求的是高德地圖的web API,但是需要傳經緯度,于是我一開始是這樣寫的:

wx.getLocation({
  type: 'gcj02',
  success: function(res) {
    var latitude = res.latitude
    var longitude = res.longitude
  }
})      

相信很多初學者到此就OK了,但是一運作發現:诶怎麼什麼都沒有?

哦,忘了說了,微信小程式中的“自動”彈窗提示是需要在app.json中配置的!

"permission": {
  "scope.userLocation": {
    "desc": "請确認授權,您的授權資訊将隻被用于小程式運作期間,且隻在小程式内部"
  }
}      

到這裡,在你剛進入頁面(如果寫在onLoad或onShow中)或者點選某按鈕觸發(寫在事件中)時就能看到一個極其類似小程式彈框API ​

​wx.showToast()​

​ 的提示框了。

你是否到這裡就滿足了?

當我信心滿滿的送出代碼後卻換來了老大的“無能狂怒”:“為什麼在使用者點選‘取消’按鈕時沒有提示!”、“為什麼不在使用者拒絕授權以後下一次想要觸發相應功能時給個提醒?”

emmmmmmm我也沒注意過這玩意啊…

情急之下,又找到了​

​wx.getLocation()​

​的文檔,發現裡面有這麼一個說明:

淺談微信小程式授權應用

接口調用失敗?

肯定是分為好多種情況的,但是毫無疑問的是:如果使用者拒絕了授權,那麼相應的資訊就不可能傳回,應該也算是“調用失敗”…吧?

wx.getLocation({
  type: 'gcj02', //傳回可以用于wx.openLocation的經緯度
  success: function(res) {
    var latitude = res.latitude
    var longitude = res.longitude
  },
  fail(){
    console.log('使用者拒絕了授權')
  }
})      
淺談微信小程式授權應用

果然。

那接下來我們唯一需要做的就是:在fail中給出使用者提示,并引導使用者去授權!

​wx.openSetting​

​​,打開設定頁!

一般用于“二次授權”。其中屬性 ​​

​authSetting​

​ 中(scope對象)包含了使用者的操作配置!
wx.showModal({
   title: '提醒!',
   content: '您拒絕了位置授權,将無法使用大部分功能,點選确定重新擷取授權',
   success(res) {
     //如果點選确定
     if (res.confirm) {
       wx.openSetting({ //打開設定頁
        success(res) { //成功,傳回頁面回調
          //如果同意了位置授權則userLocation=true
          if (res.authSetting["scope.userLocation"]) { //授權中如果有位置授權則執行邏輯
            /*後續代碼:比如:重新整理頁面/重新調用函數*/
          }
        }
      })
    }
  }
})      
淺談微信小程式授權應用

到這裡其實就很完善了(在微信看來)。但是你會發現:如果使用者第二次仍然拒絕授權,那麼就不再有機會了(除非清除緩存重新進入或者再次調用getLocation API)。

淺談微信小程式授權應用

是以,從這一點看,你可以選擇更為友善的:百度/高德地圖API

如果用web API,需要在微信中配置高德/百度的域名:
淺談微信小程式授權應用
然後回到開發者工具,重新整理應該就可以了。有些麻煩 建議它們的另一個服務:微信 SDK(高德)/微信小程式JavaScript API(百度)
  • ​​百度地圖-微信小程式JavaScript API配置​​
  • ​​高德地圖-微信 SDK配置​​

使用者資訊授權

歐呦,這個就有的說了:微信小程式“ 擷取使用者資訊 ”的機制很早就改了。或許是不想讓開發者對使用者“随意”造成困擾——畢竟有的使用者上來隻是為了“逛一圈”,于是增加了“ 隻有觸發button才能彈窗 ”的功能。

看一下新版授權資訊機制

<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">授權</button>

//js
onLoad(options){
  this.userAuthorized();
},
getUserInfo(event){
  const userInfo=event.detail.userInfo;
  this.setData({
    userInfo:userInfo
  })
},
authorized(){
  wx.getSetting(){
    success:data=>{
      if(data.authSetting["scope.userInfo"]){
        wx.getUserInfo({
          success:data=>{
            this.setData({
              userInfo:data.userInfo
            })
          }
        })
      }
    }
  }
}      

那麼,從老版小程式一路跟進的使用者就該問了:有了open-type為什麼還要有getUserInfo呢?

要知道,open-type隻是為了(而且隻能)擷取使用者頭像、昵稱這些簡單(可能在微信開來也沒啥用的)資訊,這一點上​

​<button>​

​​和原先的​

​<open-type></open-type>​

​​沒有什麼差別,但是!其實擷取完整使用者資訊(更多的如:手機号、id、使用者授權相關),最重要的是“ 登入 ”,這一步就涉及到和伺服器的互動了。

登入操作在伺服器端是有一套非常完整的邏輯的,并不像我們所想的那麼簡單,這一點以後再說。

當然,上面的代碼隻是闡述一下新版微信小程式改進的地方,下面的才是重點:

自定義button元件實作使用者授權登入

我們在于主檔案夾同級建立img-button檔案夾,作為button元件的地方。

img-button.wxml

<button bind:getuserinfo="onGetUserInfo" open-type="{{openType}}" plain="{{true}}" class="container">
  <slot name="img"></slot>
</button>      

這裡的bind後面必須跟userinfo,這是button元件的API。

淺談微信小程式授權應用

img-button.js

Component({
  // “備注項”——啟用“插槽”
  options:{
    multipleSlot:true
  },
  prototies:{
    openType:{
      type:String
    }
  },
  methods:{
    onGetUserInfo(event){
      this.triggerEvent('getUserinfo',event.detail,{})
    }
  }
})      

元件都有一項“必備屬性”——prototies。(就如同vue中的props——用于接收資料,規範格式)

接收誰的資料? —— 主wxml中傳來的資料!

既然有接收,就有傳出。不然要元件幹嘛。

對!在methods裡面,元件“告訴”調用它的元素——用getUserInfo定義事件,給你傳一個值event.detail

(這個“getUserInfo”将作為首頁面bind的事件——這裡機制其實和vue中的“$emit”->子元件向父元件傳值,是一樣的)

這樣“一來一往”,自定義元件内部和外面調用檔案就能“互相通路”了。

我們在主檔案的json檔案裡添加“對自定義元件檔案的通路”:

main.json

"usingComponents":{
  "v-button":"../img-button/img-button"
}      

main.wxml

<v-button wx:if="{{!authorized}}" open-type="getUserInfo" class="..."
      bind:getUserinfo="onGetUserInfo">
  <image slot="img" class="..." src="圖檔路徑" /><!-- 更改button樣式,用圖檔觸發 -->
</v-button>
<view wx:if="{{authorized}}" class="...">
  <image src="{{userInfo.avatarUrl}}" class="..." />
  <text>{{userInfo.nickName}}</text>
</view>      

這裡還真有一點需要注意的:調用元件時的bind的事件名就是自定義元件内部傳出來的值!(而且必須是)(這一點和​​上面button元件裡面​​不同)

data:{
  authorized:false,
  userInfo:null
},
onLoad(options){
  this.userAuthorized();
},
onGetUserInfo(event){
  const userInfo=event.detail.userInfo;   //取出元件内部傳出來的值
  if(userInfo){
    this.setData({
      userInfo,
      authorized:true
    })
  }
},
userAuthorized(){
  wx.getSetting({
    success:data=>{
      if(data.authSetting['scope.userInfo']){
        wx.getUserInfo({
          success:data=>{
            this.setData({
              authorized:true,
              userInfo:data.userInfo
            })
          }
        })
      }else{
        wx.showToast({
          title:'抱歉!請檢查微信後再試',
          icon:'none',
          duration:1200
        })
      }
    }
  })
}      
由我開源并維護的小項目:微信小程式功能元件庫 已釋出至github,歡迎star!歡迎提issues!想要參與維護和開發歡迎留言!
配套展示小程式:

繼續閱讀