淺談微信小程序授權應用
發表時(shí)間:2020-11-6
發布人(rén):融晨科技
浏覽次數:48
微信小程序中關乎“授權”的(de),抛開各路“牛鬼蛇神”不(bù)談,大(dà)體上(shàng)也(yě)就(jiù)兩種:
- 位置授權
- 用戶信息授權
切記的(de)是(shì):在(zài)微信一直打着的(de)“用戶至上(shàng)”的(de)旗号下,幾乎一切用戶相關的(de)應用都需要(yào / yāo)用戶手動授權!所以(yǐ)必須要(yào / yāo)有提示的(de)。
位置授權
昨天完成了(le/liǎo)微信小程序項目的(de)最後一點内容,裏面我加了(le/liǎo)個(gè)“點擊自動定位”的(de)功能,請求的(de)是(shì)高德地(dì / de)圖的(de)web API,但是(shì)需要(yào / yāo)傳經緯度,于(yú)是(shì)我一開始是(shì)這(zhè)樣寫的(de):
wx.getLocation({
type: 'gcj02',
success: function(res) {
var latitude = res.latitude
var longitude = res.longitude
}
})
相信很多初學者到(dào)此就(jiù)OK了(le/liǎo),但是(shì)一運行發現:诶怎麽什麽都沒有?
哦,忘了(le/liǎo)說(shuō)了(le/liǎo),微信小程序中的(de)“自動”彈窗提示是(shì)需要(yào / yāo)在(zài)app.json中配置的(de)!
"permission": {
"scope.userLocation": {
"desc": "請确認授權,您的(de)授權信息将隻被用于(yú)小程序運行期間,且隻在(zài)小程序内部"
}
}
到(dào)這(zhè)裏,在(zài)你剛進入頁面(如果寫在(zài)onLoad或onShow中)或者點擊某按鈕觸發(寫在(zài)事件中)時(shí)就(jiù)能看到(dào)一個(gè)極其類似小程序彈框API wx.showToast()
的(de)提示框了(le/liǎo)。
你是(shì)否到(dào)這(zhè)裏就(jiù)滿足了(le/liǎo)?
當我信心滿滿的(de)提交代碼後卻換來(lái)了(le/liǎo)老大(dà)的(de)“無能狂怒”:“爲(wéi / wèi)什麽在(zài)用戶點擊‘取消’按鈕時(shí)沒有提示!”、“爲(wéi / wèi)什麽不(bù)在(zài)用戶拒絕授權以(yǐ)後下一次想要(yào / yāo)觸發相應功能時(shí)給個(gè)提醒?”
emmmmmmm我也(yě)沒注意過這(zhè)玩意啊…
情急之(zhī)下,又找到(dào)了(le/liǎo)wx.getLocation()
的(de)文檔,發現裏面有這(zhè)麽一個(gè)說(shuō)明:
接口調用失敗?
肯定是(shì)分爲(wéi / wèi)好多種情況的(de),但是(shì)毫無疑問的(de)是(shì):如果用戶拒絕了(le/liǎo)授權,那麽相應的(de)信息就(jiù)不(bù)可能返回,應該也(yě)算是(shì)“調用失敗”…吧?
wx.getLocation({
type: 'gcj02', //返回可以(yǐ)用于(yú)wx.openLocation的(de)經緯度
success: function(res) {
var latitude = res.latitude
var longitude = res.longitude
},
fail(){
console.log('用戶拒絕了(le/liǎo)授權')
}
})
果然。
那接下來(lái)我們唯一需要(yào / yāo)做的(de)就(jiù)是(shì):在(zài)fail中給出(chū)用戶提示,并引導用戶去授權!
wx.openSetting
,打開設置頁!
一般用于(yú)“二次授權”。其中屬性authSetting
中(scope對象)包含了(le/liǎo)用戶的(de)操作配置!
wx.showModal({
title: '提醒!',
content: '您拒絕了(le/liǎo)位置授權,将無法使用大(dà)部分功能,點擊确定重新獲取授權',
success(res) {
//如果點擊确定
if (res.confirm) {
wx.openSetting({ //打開設置頁
success(res) { //成功,返回頁面回調
//如果同意了(le/liǎo)位置授權則userLocation=true
if (res.authSetting["scope.userLocation"]) { //授權中如果有位置授權則執行邏輯
/*後續代碼:比如:刷新頁面/重新調用函數*/
}
}
})
}
}
})
到(dào)這(zhè)裏其實就(jiù)很完善了(le/liǎo)(在(zài)微信看來(lái))。但是(shì)你會發現:如果用戶第二次仍然拒絕授權,那麽就(jiù)不(bù)再有機會了(le/liǎo)(除非清除緩存重新進入或者再次調用getLocation API)。
所以(yǐ),從這(zhè)一點看,你可以(yǐ)選擇更爲(wéi / wèi)方便的(de):百度/高德地(dì / de)圖API
如果用web API,需要(yào / yāo)在(zài)微信中配置高德/百度的(de)域名:
然後回到(dào)開發者工具,刷新應該就(jiù)可以(yǐ)了(le/liǎo)。有些麻煩
建議它們的(de)另一個(gè)服務:微信 SDK(高德)/微信小程序JavaScript API(百度)
- 百度地(dì / de)圖-微信小程序JavaScript API配置
- 高德地(dì / de)圖-微信 SDK配置
用戶信息授權
歐呦,這(zhè)個(gè)就(jiù)有的(de)說(shuō)了(le/liǎo):微信小程序“ 獲取用戶信息 ”的(de)機制很早就(jiù)改了(le/liǎo)。或許是(shì)不(bù)想讓開發者對用戶“随意”造成困擾——畢竟有的(de)用戶上(shàng)來(lái)隻是(shì)爲(wéi / wèi)了(le/liǎo)“逛一圈”,于(yú)是(shì)增加了(le/liǎo)“ 隻有觸發button才能彈窗 ”的(de)功能。
看一下新版授權信息機制
<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
})
}
})
}
}
}
}
那麽,從老版小程序一路跟進的(de)用戶就(jiù)該問了(le/liǎo):有了(le/liǎo)open-type爲(wéi / wèi)什麽還要(yào / yāo)有getUserInfo呢?
要(yào / yāo)知道(dào),open-type隻是(shì)爲(wéi / wèi)了(le/liǎo)(而(ér)且隻能)獲取用戶頭像、昵稱這(zhè)些簡單(可能在(zài)微信開來(lái)也(yě)沒啥用的(de))信息,這(zhè)一點上(shàng)<button>
和(hé / huò)原先的(de)<open-type></open-type>
沒有什麽區别,但是(shì)!其實獲取完整用戶信息(更多的(de)如:手機号、id、用戶授權相關),最重要(yào / yāo)的(de)是(shì)“ 登錄 ”,這(zhè)一步就(jiù)涉及到(dào)和(hé / huò)服務器的(de)交互了(le/liǎo)。
登錄操作在(zài)服務器端是(shì)有一套非常完整的(de)邏輯的(de),并不(bù)像我們所想的(de)那麽簡單,這(zhè)一點以(yǐ)後再說(shuō)。
當然,上(shàng)面的(de)代碼隻是(shì)闡述一下新版微信小程序改進的(de)地(dì / de)方,下面的(de)才是(shì)重點:
自定義button組件實現用戶授權登錄
我們在(zài)于(yú)主文件夾同級建立img-button文件夾,作爲(wéi / wèi)button組件的(de)地(dì / de)方。
img-button.wxml
<button bind:getuserinfo="onGetUserInfo" open-type="{{openType}}" plain="{{true}}" class="container">
<slot name="img"></slot>
</button>
這(zhè)裏的(de)bind後面必須跟userinfo,這(zhè)是(shì)button組件的(de)API。
img-button.js
Component({
// “備注項”——啓用“插槽”
options:{
multipleSlot:true
},
prototies:{
openType:{
type:String
}
},
methods:{
onGetUserInfo(event){
this.triggerEvent('getUserinfo',event.detail,{})
}
}
})
組件都有一項“必備屬性”——prototies。(就(jiù)如同vue中的(de)props——用于(yú)接收數據,規範格式)
接收誰的(de)數據? —— 主wxml中傳來(lái)的(de)數據!
既然有接收,就(jiù)有傳出(chū)。不(bù)然要(yào / yāo)組件幹嘛。
對!在(zài)methods裏面,組件“告訴”調用它的(de)元素——用getUserInfo定義事件,給你傳一個(gè)值event.detail
(這(zhè)個(gè)“getUserInfo”将作爲(wéi / wèi)主頁面bind的(de)事件——這(zhè)裏機制其實和(hé / huò)vue中的(de)“$emit”->子(zǐ)組件向父組件傳值,是(shì)一樣的(de))
這(zhè)樣“一來(lái)一往”,自定義組件内部和(hé / huò)外面調用文件就(jiù)能“互相訪問”了(le/liǎo)。
我們在(zài)主文件的(de)json文件裏添加“對自定義組件文件的(de)訪問”:
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>
這(zhè)裏還真有一點需要(yào / yāo)注意的(de):調用組件時(shí)的(de)bind的(de)事件名就(jiù)是(shì)自定義組件内部傳出(chū)來(lái)的(de)值!(而(ér)且必須是(shì))(這(zhè)一點和(hé / huò)上(shàng)面button組件裏面不(bù)同)
main.js
data:{
authorized:false,
userInfo:null
},
onLoad(options){
this.userAuthorized();
},
onGetUserInfo(event){
const userInfo=event.detail.userInfo; //取出(chū)組件内部傳出(chū)來(lái)的(de)值
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
})
}
}
})
}
由我開源并維護的(de)小項目:微信小程序功能組件庫 已發布至github,歡迎star!歡迎提issues!想要(yào / yāo)參與維護和(hé / huò)開發歡迎留言!
配套展示小程序:
