小程序的部分接口需要经过用户授权同意才能调用。授权功能实现,是一个不可回避,又有点扯不清的话题,这里我们做一个详细深入的分析。
最新的小程序各种授权,按使用范围分成了多个scope
,详细的scope
,可以参看小程序官方文档,这里我们就不赘诉了。地址如下:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html
其中,scope.userInfo
用户信息授权,用法比较特殊,我们下一节再作讲解。
我这里先把scope.userInfo
之外的其他授权方法基本一致的做一个详细的探讨。
详细完成授权步骤如下:
一、使用[wx.openSetting]获取授权状态
官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/wx.getSetting.html
官方示例:
wx.getSetting({
success(res) {
console.log(res.authSetting)
// res.authSetting = {
// "scope.userInfo": true,
// "scope.userLocation": true
// }
}
})
注意:
上面示例官方并没有详细讲解,返回的res.authSetting
中,每一个具体的scope
授权,其实并不是true
和false
那么简单。
返回的详细结果可能如下:
{
errMsg:"getSetting:ok",
authSetting:{
scope.userInfo:true
}
}
甚至可能是这样的:
{
errMsg:"getSetting:ok",
authSetting:{}
}
除了errMsg
信息外,我们关注的重点是在authSetting
中去取我们想要的值,但是,我们发现,可能我们想要的结果并没有在里面,所以这里就是我们处理授权的关键了。
所以,在判断是否授权的这一步中,我们要做的工作如下:
- 判断授权我们想要的
scope
是否存在;
- 再判断是
true
还是false
。
这一步中:
scope
为空,表示授权状态为初始状态,此时,可调起自动弹窗,让用户授权;
scope
为trues
,表示用户已授权,如为falses
,则表示用户拒绝了授权。
而小程序授权功能的核心逻辑是这样的,
重点的重点:
小程序在第一次调起授权之后(自动弹窗),如果用户拒绝了授权,也就是上面返回的结果为false的话,我们想要重新再调起(自动弹窗),需要用户自己手动删除程序,或者是退出小程序,等待一段时间再进去才能再次调起授权(自动弹窗),这种方式,明显是一种不可取的用户体验极差的方法。
幸好,官方有一个用户可以设置所有授权的页面,也就是wx.openSetting
接口。
该功能如下图:
](08ac31c3-c38f-48c8-a13e-763ab5b4f9f3_files/2a051386-862b-4004-bbe0-59b710d177f4.png)
所以,到这里明白了整个授权的逻辑后,该怎么实现完整的授权功能,我们心里就有数了。
二、使用 wx.openSetting 配合完成授权
实现授权功能的逻辑如下:
- 使用[wx.openSetting]获取授权状态
- 结果为空 — 使用
wx.authorize
弹出授权 - 结果为false — 弹窗进行说明,引导用户到权限设置页面(弹窗可使用
wx.showModal
,去设置页使用wx.openSetting
) - 结果为true — 用户已授权,正常进行自己的业务逻辑即可。
- 结果为空 — 使用
三、完整实例代码:
这里以位置授权为例:
//在地图位置选择
chooseLocation(){
const that = this
wx.getSetting({
success(res){
console.log(res)
console.log(res.authSetting['scope.userLocation'])
if(res.authSetting['scope.userLocation'] ===''){
wx.authorize({
scope: 'scope.userLocation',
success() {
//调用地图的查询位置功能
//doSomeThing()
}
})
}else if(res.authSetting['scope.userLocation'] === false){
wx.showModal({
title: '提示',
content: '需要允许使用地理位置权限,请点击“确定”去授权后再使用位置。',
success(res) {
if (res.confirm) {
console.log('用户点击确定')
wx.openSetting({
success(res) {
console.log(res.authSetting)
}
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}else{
//调用地图的查询位置功能
//doSomeThing()
}
}
})
},
ps:最新位置授权,需要在app.json做用途声明,如下代码最后的permission
“`节点申明,详细你查阅官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#permission
{
"pages":[
……
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black",
"navigationStyle": "default"
},
"tabBar": {
……
},
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于导航线路展示"
}
}
}