很久之前的微信小程序授权流程记录

  • 技术栈:React、Taro、TS

在微信小程序中,打开摄像头、麦克风,获取地理位置等接口,都需要经过授权才能调用,详见微信官方文档

既然每次都需要授权,那我每次使用前调用一次 wx.authorize不就得了?

js 复制代码
 Taro.authorize({
    scope: 'scope.camera',
    success: (res) => {
         // 用户已经同意小程序使用摄像头功能,可以进行下一步操作了(如调用扫码)
         // Taro.scanCode()
    },
    fail: (err) => {
      // 拒绝授权了
    },

第一次调用时,出现了令人激动的绿色弹框!

手抖点了拒绝,尝试再次点击(调用wx.authorize时),发现没反应了???

仔细阅读了官方文档,发现了这句话

如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。

那么如果之前拒绝授权呢?没说,但实操发现也不会出现弹框。

寻找思路:

官方文档的示例中,wx.getSettingwx.authorize搭配使用,其作用是查询授权信息。

wx.getSetting调用成功返回的信息打印出来

发现authSetting中记录了用户授权结果,刚才拒绝了授权,所以scope.camera是false

那么,可以得到上次授权结果了,需要做的是在上次拒绝之后还能重新询问授权。wx.openSetting)可以满足这一需求

调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限

梳理一下整个流程

进一步调试wx.openSetting,总结出其与操作流程的对应关系

wx.getSetting查看的权限情况 说明 所需操作
res.authSetting['scope.record']===true 之前询问过这个权限,并且用户已经同意了 已经有这个权限了,调用api即可
res.authSetting['scope.record']===false 之前询问过这个权限,但是用户拒绝了 需要跳到小程序的设置界面(openSetting)
res.authSetting['scope.record']不存在 还没有询问过这个权限 用wx.authorize这个api询问用户获取权限

(注:这里借用了一个大佬的思路,但是文章链接现在找不到了)

打开小程序的设置页面需要用户主动主动点击触发,所以这里加一个modal,用户点击确定时调用openSetting

上代码

可以封装为异步函数便于使用

js 复制代码
import Taro from "@tarojs/taro"

/**
 *
 * @param {*} scopeStr // 'scope.record' // 权限列表 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html
 * @returns
 */
export const checkPermisson = (scopeStr) => {
  return new Promise((resolve, reject) => {
    Taro.getSetting({
      success: async (res) => {
        const authSettingObj = res.authSetting
        if (authSettingObj[scopeStr] === true) {
          // 当前已经有权限了
          return resolve()
        } else if (authSettingObj[scopeStr] === false) {
          // 之前问过权限,但是拒绝了
          try {
            await openSetting(scopeStr)
            return resolve()
          } catch {
            return reject()
          }
        } else {
          // 还没问过权限
          // 去请求授权
          Taro.authorize({
            scope: scopeStr,
            success: (res) => {
              return resolve()
            },
            fail: async (err) => {
              // 拒绝授权了
              // 打开setting
              try {
                await openSetting(scopeStr)
                return resolve()
              } catch {
                return reject()
              }
            },
          })
        }
      },
    })
  })
}

// 打开设置权限的页面 去设置权限 通过showModal去触发点击
export const openSetting = (scopeStr) => {
  return new Promise((resolve, reject) => {
    Taro.showModal({
      title: '温馨提示',
      content: '请授权微信小程序相关权限,以使用更多功能',
      success: (res) => {
        if (res.confirm) {
          Taro.openSetting({
            success: function (res) {
              console.log('打开权限设置页面', res)
              const authSettingObj = res.authSetting
              if (scopeStr) {
                // 有指定去获取的权限
                if (authSettingObj[scopeStr] === true) {
                  return resolve()
                } else {
                  return reject()
                }
              } else {
                // 没有指定去获取的权限
                return resolve()
              }
            },
          })
        } else {
          return reject()
        }
      },
      fail: (err) => {
        return reject()
      },
    })
  })
}

使用示例:

js 复制代码
onScan = async () => {
    try {
      await checkPermisson('scope.camera');
      Taro.scanCode({
        scanType: ['qrCode'],
        success: (res) => {
          console.log(res);
          
        },
        fail: (res) => {}
      })
    } catch (e) {
      console.log(e, '获取权限失败');
    }
  }

其他问题

在使用getLocation获取地址时报错 {"errMsg":"getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json"}

报错信息很明确,需要在app.json加requiredPrivateInfos

解决方法:在app.config.ts加入

js 复制代码
 permission: {
  "scope.userLocation": {
    "desc": "你的位置信息将用于小程序位置接口的坐标展示" 
  }
},
requiredPrivateInfos: [
  "getLocation"
],

微信官方文档提到:

自 2022 年 7 月 14 日后发布的小程序,使用以下8个地理位置相关接口时,需要声明该字段,否则将无法正常使用。2022 年 7 月 14 日前发布的小程序不受影响。

...

注:若使用以上接口,均需在小程序管理后台,「开发」-「开发管理」-「接口设置」中自助开通该接口权限。

相关推荐
迷雾漫步者1 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-2 小时前
验证码机制
前端·后端
燃先生._.3 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖4 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235244 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240255 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar5 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人5 小时前
前端知识补充—CSS
前端·css
GISer_Jing6 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试