• 小程序隐私保护授权处理方式之弹窗组件


    小程序隐私保护授权弹窗组件
    调用wx.getUserProfile进行授权时,返回错误信息:{errMsg: “getUserProfile:fail api scope is not declared in the privacy agreement”, errno: 112} 是因为微信小程序登录,增加了用户是否查看隐私协议的验证,不跳转到隐私协议,就不让用户登录。

    8 月 28 更新:今天才发现小程序可以使用页面的生命周期,对其进行了简化,只需要使用引入组件即可,不再需要任何其它代码

    8 月 29 更新:采纳网页 Liu 的方案,解决多个 tabbar 情况下同意之后还有弹窗的问题

    注意事项
    2023 年 9 月 15 号之前,默认不会启用隐私相关功能,所以检测不到需要弹窗的情况,可以在 app.json 中配置 "__usePrivacyCheck__": true 之后,接口才可以检测到是否需要弹窗。个人实际情况:我在开发者工具中配置了 "__usePrivacyCheck__": true ,needAuthorization 无论如何返回的都是 false,但在真机模拟的情况下可以返回 true
    自动打开隐私保护指引界面需在「小程序管理后台」配置《小程序用户隐私保护指引》,官方用户隐私保护指引填写说明。

    使用方法

    1、app.json添加一行:

    "__usePrivacyCheck__": true

    2、拷贝 component 文件夹中的 privacy 文件夹到小程序项目中的组件目录

    3、在 page.json 中引入组件

    1. {
    2. "usingComponents": {
    3. "Privacy": "/component/privacy/privacy"
    4. }
    5. }
    1. 在 page.wxml 中使用组件
    2. <Privacy />
      

    3. 可以在所有使用了隐私接口的页面都加上该组件,授权一次之后使用所有隐私接口不再需要授权
      取消授权

      微信中「微信下拉-最近-最近使用的小程序」中删除小程序可取消授权。
      开发者工具中「清除模拟器缓存-清除授权数据」可取消授权

    相关链接

    官方:小程序隐私协议开发指南

    代码模块

    1、技术:taro + vue3 + ts
    2、创建component组件Privacy文件,在需要授权的页面添加就阔以

    1. wxml 原生微信写法

     

    1. // 1. 微信wxml的写法
    2. // component/privacy/privacy.wxml
    3. <view class="privacy" wx:if="{{showPrivacy}}">
    4. <view class="content">
    5. <view class="title">隐私保护指引</view>
    6. <view class="des">
    7. 在使用当前小程序服务之前,请仔细阅读<text class="link" bind:tap="openPrivacyContract">{{privacyContractName}}</text>。如你同意{{privacyContractName}},请点击“同意”开始使用。
    8. </view>
    9. <view class="btns">
    10. <button class="item reject" bind:tap="exitMiniProgram">拒绝</button>
    11. <button id="agree-btn" class="item agree" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button>
    12. </view>
    13. </view>
    14. </view>
    15. // 2、js 文件
    16. // component/privacy/privacy.js
    17. Component({
    18. /**
    19. * 组件的初始数据
    20. */
    21. data: {
    22. privacyContractName: '',
    23. showPrivacy: false
    24. },
    25. /**
    26. * 组件的生命周期
    27. */
    28. pageLifetimes: {
    29. show() {
    30. const _ = this
    31. wx.getPrivacySetting({
    32. success(res) {
    33. if (res.errMsg == "getPrivacySetting:ok") {
    34. _.setData({
    35. privacyContractName: res.privacyContractName,
    36. showPrivacy: res.needAuthorization
    37. })
    38. }
    39. }
    40. })
    41. }
    42. },
    43. /**
    44. * 组件的方法列表
    45. */
    46. methods: {
    47. // 打开隐私协议页面
    48. openPrivacyContract() {
    49. const _ = this
    50. wx.openPrivacyContract({
    51. fail: () => {
    52. wx.showToast({
    53. title: '遇到错误',
    54. icon: 'error'
    55. })
    56. }
    57. })
    58. },
    59. // 拒绝隐私协议
    60. exitMiniProgram() {
    61. // 直接退出小程序
    62. wx.exitMiniProgram()
    63. },
    64. // 同意隐私协议
    65. handleAgreePrivacyAuthorization() {
    66. const _ = this
    67. _.setData({
    68. showPrivacy: false
    69. })
    70. },
    71. },
    72. })
    73. // 3、样式
    74. /* component/privacy/privacy.wxss */
    75. .privacy {
    76. position: fixed;
    77. top: 0;
    78. right: 0;
    79. bottom: 0;
    80. left: 0;
    81. background: rgba(0, 0, 0, .5);
    82. z-index: 9999999;
    83. display: flex;
    84. align-items: center;
    85. justify-content: center;
    86. }
    87. .content {
    88. width: 632rpx;
    89. padding: 48rpx;
    90. box-sizing: border-box;
    91. background: #fff;
    92. border-radius: 16rpx;
    93. }
    94. .content .title {
    95. text-align: center;
    96. color: #333;
    97. font-weight: bold;
    98. font-size: 32rpx;
    99. }
    100. .content .des {
    101. font-size: 26rpx;
    102. color: #666;
    103. margin-top: 40rpx;
    104. text-align: justify;
    105. line-height: 1.6;
    106. }
    107. .content .des .link {
    108. color: #07c160;
    109. text-decoration: underline;
    110. }
    111. .btns {
    112. margin-top: 48rpx;
    113. display: flex;
    114. }
    115. .btns .item {
    116. justify-content: space-between;
    117. width: 244rpx;
    118. height: 80rpx;
    119. display: flex;
    120. align-items: center;
    121. justify-content: center;
    122. border-radius: 16rpx;
    123. box-sizing: border-box;
    124. border: none;
    125. }
    126. .btns .reject {
    127. background: #f4f4f5;
    128. color: #909399;
    129. }
    130. .btns .agree {
    131. background: #07c160;
    132. color: #fff;
    133. }
    1. taro框架vue版写法
    1. // #### taro框架的写法
    2. <template>
    3. <view class="privacy_box" v-if="showPrivacy">
    4. <view class="content">
    5. <view class="title">隐私保护指引</view>
    6. <view class="des">
    7. 在使用当前小程序服务之前,请仔细阅读
    8. <text class="link" @click="openPrivacyContract">{{ privacyContractName }}</text>
    9. 。如你同意{{ privacyContractName }},请点击“同意”开始使用。
    10. </view>
    11. <view class="btns">
    12. <button class="item reject" @click="exitMiniProgram">拒绝</button>
    13. <button
    14. id="agree-btn"
    15. class="item agree"
    16. open-type="agreePrivacyAuthorization"
    17. @agreeprivacyauthorization="handleAgreePrivacyAuthorization"
    18. >
    19. 同意
    20. </button>
    21. </view>
    22. </view>
    23. </view>
    24. </template>
    25. <script setup lang="ts">
    26. import { ref } from "vue";
    27. import Taro, { useDidShow } from "@tarojs/taro";
    28. const showPrivacy = ref<boolean>(false);
    29. const privacyContractName = ref<string>("");
    30. // 打开隐私协议页面
    31. const openPrivacyContract = () => {
    32. Taro.openPrivacyContract({
    33. fail: () => {
    34. Taro.showToast({
    35. title: "遇到错误",
    36. icon: "error",
    37. });
    38. },
    39. });
    40. };
    41. // 拒绝隐私协议
    42. const exitMiniProgram = () => {
    43. Taro.exitMiniProgram();
    44. };
    45. // 同意隐私协议
    46. const handleAgreePrivacyAuthorization = () => {
    47. showPrivacy.value = false;
    48. };
    49. useDidShow(() => {
    50. Taro.getPrivacySetting({
    51. success(res) {
    52. if (res.errMsg == "getPrivacySetting:ok") {
    53. privacyContractName.value = res.privacyContractName;
    54. showPrivacy.value = res.needAuthorization;
    55. }
    56. },
    57. });
    58. });
    59. </script>
    60. <style lang="scss">
    61. .privacy_box {
    62. position: fixed;
    63. top: 0;
    64. right: 0;
    65. bottom: 0;
    66. left: 0;
    67. background: rgba(0, 0, 0, 0.5);
    68. z-index: 9999999;
    69. display: flex;
    70. align-items: center;
    71. justify-content: center;
    72. .content {
    73. width: 632rpx;
    74. padding: 48rpx;
    75. box-sizing: border-box;
    76. background: #fff;
    77. border-radius: 16rpx;
    78. }
    79. .content .title {
    80. text-align: center;
    81. color: #333;
    82. font-weight: bold;
    83. font-size: 32rpx;
    84. }
    85. .content .des {
    86. font-size: 26rpx;
    87. color: #666;
    88. margin-top: 40rpx;
    89. text-align: justify;
    90. line-height: 1.6;
    91. }
    92. .content .des .link {
    93. color: #07c160;
    94. text-decoration: underline;
    95. }
    96. .btns {
    97. margin-top: 48rpx;
    98. display: flex;
    99. }
    100. .btns .item {
    101. justify-content: space-between;
    102. width: 244rpx;
    103. height: 80rpx;
    104. display: flex;
    105. align-items: center;
    106. justify-content: center;
    107. border-radius: 16rpx;
    108. box-sizing: border-box;
    109. border: none;
    110. }
    111. .btns .item::after {
    112. border: 0;
    113. }
    114. .btns .reject {
    115. background: #f4f4f5;
    116. color: #909399;
    117. }
    118. .btns .agree {
    119. background: #07c160;
    120. color: #fff;
    121. }
    122. }
    123. </style>

  • 相关阅读:
    笔试强训48天——day14
    一个开源且完全自主开发的国产网络协议栈
    回收站没有刚刚删除的文件原因|找回方法|解决方案
    关于标准库中的string类 - c++
    计算机网络【第一章】
    盘点 | 跨平台桌面应用开发的5大主流框架
    重构优化第三方查询接口返回大数据量的分页问题
    openstack aarch64 arm64 kylin pip方式下载 nova 23.2.2 离线whl包
    常量左值引用作为形参来接收右值引用实参所带来的问题
    增加软件投入的重要性:提升自动化程度与用户界面设计的价值
  • 原文地址:https://blog.csdn.net/linfanhehe/article/details/132739240