微信小程序开发之授权权限管理

微信小程序的部分接口需要经过用户授权同意才能调用。我们把这些接口按使用范围分成多个 scope ,用户选择对 scope 来进行授权,当授权给一个 scope 之后,其对应的所有接口都可以直接使用。

此类接口调用时

如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;
如果用户已授权,可以直接调用接口;
如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。

获取用户授权设置

开发者可以使用 wx.getSetting 获取用户当前的授权状态。

打开设置界面

用户可以在小程序设置界面(「右上角」 - 「关于」 - 「右上角」 - 「设置」)中控制对该小程序的授权状态。

开发者可以调用 wx.openSetting 打开设置界面,引导用户开启授权。

提前发起授权请求

开发者可以使用 wx.authorize 在调用需授权 API 之前,提前向用户发起授权请求。

scope 列表

scope 对应接口 描述
scope.userInfo wx.getUserInfo 用户信息
scope.userLocation wx.getLocationwx.chooseLocation 地理位置
scope.userLocationBackground wx.startLocationUpdateBackground 后台定位
scope.address wx.chooseAddress 通讯地址
scope.invoiceTitle wx.chooseInvoiceTitle 发票抬头
scope.invoice wx.chooseInvoice 获取发票
scope.werun wx.getWeRunData 微信运动步数
scope.record wx.startRecord 录音功能
scope.writePhotosAlbum wx.saveImageToPhotosAlbumwx.saveVideoToPhotosAlbum 保存到相册
scope.camera camera 组件 摄像头

授权有效期

一旦用户明确同意或拒绝过授权,其授权关系会记录在后台,直到用户主动删除小程序。

最佳实践

在真正需要使用授权接口时,才向用户发起授权申请,并在授权申请中说明清楚要使用该功能的理由。

注意事项

wx.authorize({scope: "scope.userInfo"}),不会弹出授权窗口,请使用

<button open-type="getUserInfo"/>

需要授权 scope.userLocation、scope.userLocationBackground 时必须配置地理位置用途说明。在全局的app.json文件里配置permission:

{
  "pages": ["pages/index/index"],
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序位置接口的效果展示" // 高速公路行驶持续后台定位
    }
  }
}

后台定位

与其它类型授权不同的是,scope.userLocationBackground 不会弹窗提醒用户。需要用户在设置页中,主动将“位置信息”选项设置为“使用小程序期间和离开小程序后”。开发者可以通过调用wx.openSetting,打开设置页。

封装公共的授权方法

飘易封装了一下获取授权的方法,可以供开发者在需要的地方方便地调用授权:

/*
* 检查权限
* scope: 权限字符串,如 scope.writePhotosAlbum
* msg: 提示字符串,如 保存到系统相册需要授权
* callback: 回调函数
*/    
checkScope: function (scope, msg, callback) {
	//查询权限
	wx.showLoading({
		title: '检查授权情况',
		mask: true
	})
	wx.getSetting({
		success(res) {
			wx.hideLoading();
			if (!res.authSetting[scope]) {
				// 请求授权
				wx.authorize({
					scope: scope,
					success() {
						// 获得授权
						typeof callback === 'function' && callback();
					},
					fail() {
						wx.showModal({
							content: msg,//'保存到系统相册需要授权',
							confirmText: '授权',
							showCancel: false,
							success(res) {
								if (res.confirm) {
									wx.openSetting({
										success(res) {
											if (res.authSetting[scope] === true) {
												typeof callback === 'function' && callback();
											}
										}
									})
								}
							},
							fail() {
							    wx.showToast({
									title: '打开设置页失败',
									icon: 'none',
								})
							}
						})
					}
				})
		    } else {
				//已有授权
				typeof callback === 'function' && callback();
		    }
		},
		fail() {
			wx.hideLoading();
			wx.showToast({
				title: '获取授权失败',
				icon: 'none',
		    })
		}
	})
},

注意:getUserInfo 和 userLocationBackground 需要特殊的处理。