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

  • 技术栈: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 日前发布的小程序不受影响。

...

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

相关推荐
桂月二二37 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者4 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794484 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存