一个组件解决小程序隐私授权|技术创作特训营第一期

2023-08-28 18:52:57 浏览数 (1)

8 月 10 日微信官方发布公告 关于小程序隐私保护指引设置的公告,从 2023 年 9 月 15 日起必须用户点击同意隐私保护政策并同步给微信之后,开发者才可以调用微信提供的隐私接口。

查询相关资料

涉及隐私的接口或组件包括收集昵称/头像、位置信息、手机号、选择文件等一共有 18 组,可以在小程序官方文档中查看 隐私相关接口,绝大部分的小程序都应该至少使用过一两个隐私接口,如果不处理, 9 月 15 号之后涉及隐私的接口将无法使用,开发者要做的就是做一个弹窗提示用户阅读隐私保护指引,在用户点击“同意”按钮之后同步给微信,之后微信才允许开发者调用隐私接口,并且还会检测用户是否点击了按钮。

官方示例官方示例

首先,涉及到使用了隐私接口的小程序必须在「小程序管理后台」设置《小程序用户隐私保护指引》,微信一共提供了 4 个接口给开发者使用,分别是

  1. wx.getPrivacySetting:查询隐私授权情况
  2. wx.openPrivacyContract:跳转到隐私协议页面
  3. wx.onNeedPrivacyAuthorization:监听隐私接口需要用户授权事件
  4. wx.requirePrivacyAuthorize :模拟隐私接口调用,并触发隐私弹窗逻辑

分析

开发者可以在需要调用隐私接口时弹窗、也可以在小程序打开时弹窗,而且只需要授权一次,授权之后只要用户没有删除小程序可以一直调用用到的全部隐私接口,一番研究之后我选择在页面显示时就判断是否需要授权,授权之后以后就不需要授权了,最终确定的流程如下:

  1. 页面显示时使用 wx.getPrivacySetting 接口判断是否需要授权,需要则展示弹窗;
  2. 用户点击查看隐私保护指引,使用 wx.openPrivacyContract 接口打开隐私保护指引页面;
  3. 用户返回弹窗页面;
  4. 用户点击“拒绝”直接关闭小程序,用户点击“同意”同步给微信,关闭弹窗;

考虑到用户可能有通过分享、扫码等直接进入到某个需要调用隐私接口的界面的情况,代码需要多次复用,直接写成组件更合适,组件外部的代码越少越好。

开发组件

弹窗界面弹窗界面

首先完成组件的界面,创建一个组件文件夹 component,然后创建一个 privacy 子文件夹,再创建一个 privacy 组件,组件是一个全屏蒙版加居中弹窗,弹窗中展示标题、描述、拒绝和同意按钮,wxml和wxss代码如下:

代码语言:javascript复制
<!--component/privacy/privacy.wxml-->
<view class="privacy" wx:if="{{showPrivacy}}">
    <view class="content">
        <view class="title">隐私保护指引</view>
        <view class="des">
            在使用当前小程序服务之前,请仔细阅读<text class="link" bind:tap="openPrivacyContract">{{privacyContractName}}</text>。如你同意{{privacyContractName}},请点击“同意”开始使用。
        </view>
        <view class="btns">
            <button class="item reject" bind:tap="exitMiniProgram">拒绝</button>
            <button id="agree-btn" class="item agree" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button>
        </view>
    </view>
</view>
代码语言:javascript复制
/* component/privacy/privacy.wxss */
.privacy {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, .5);
    z-index: 9999999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.content {
    width: 632rpx;
    padding: 48rpx;
    box-sizing: border-box;
    background: #fff;
    border-radius: 16rpx;
}

.content .title {
    text-align: center;
    color: #333;
    font-weight: bold;
    font-size: 32rpx;
}

.content .des {
    font-size: 26rpx;
    color: #666;
    margin-top: 40rpx;
    text-align: justify;
    line-height: 1.6;
}

.content .des .link {
    color: #07c160;
    text-decoration: underline;
}

.btns {
    margin-top: 48rpx;
    display: flex;
}

.btns .item {
    justify-content: space-between;
    width: 244rpx;
    height: 80rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 16rpx;
    box-sizing: border-box;
    border: none;
}

.btns .reject {
    background: #f4f4f5;
    color: #909399;
}

.btns .agree {
    background: #07c160;
    color: #fff;
}
代码语言:javascript复制
// component/privacy/privacy.js
Component({
    /**
     * 组件的初始数据
     */
    data: {
        privacyContractName: '',
        showPrivacy: false
    },
    /**
     * 组件的生命周期
     */
    pageLifetimes: {
        show() {
            const _ = this
            wx.getPrivacySetting({
                success(res) {
                    if (res.needAuthorization) {
                        _.setData({
                            privacyContractName: res.privacyContractName,
                            showPrivacy: true
                        })
                    }
                }
            })
        }
    },
    /**
     * 组件的方法列表
     */
    methods: {
        // 打开隐私协议页面
        openPrivacyContract() {
            const _ = this
            wx.openPrivacyContract({
                fail: () => {
                    wx.showToast({
                        title: '遇到错误',
                        icon: 'error'
                    })
                }
            })
        },
        // 拒绝隐私协议
        exitMiniProgram() {
            // 直接退出小程序
            wx.exitMiniProgram()
        },
        // 同意隐私协议
        handleAgreePrivacyAuthorization() {
            const _ = this
            _.setData({
                showPrivacy: false
            })
        },
    },
})

完成组件之后,我们只需要在所有用到隐私接口的页面中引用组件就可以了。

使用

1. 使用时,在 page.json 中引入组件

代码语言:javascript复制
{
    "usingComponents": {
        "Privacy": "/component/privacy/privacy"
    }
}

2. 在 page.wxml 中使用组件

代码语言:javascript复制
<Privacy />

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

注意事项

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

如何取消授权进行调试

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

开源

文章代码已在 GitHub 开源,项目链接:https://github.com/94xy/miniprogram-privacy

选题思路

「小程序隐私保护指引设置」的公告发布后,开发者需要在用户同意隐私保护政策之后才能调用微信提供的隐私接口。本文选择介绍如何在小程序中设置隐私保护指引,并使用组件实现弹窗提示用户阅读隐私保护指引的功能。文章总结了具体的流程和使用方法,并提供了开源代码,为开发者提供了一种解决该问题的方式。

创作提纲

  1. 介绍背景
  2. 相关资料介绍
  3. 分析更优解决方案
  4. 组件开发过程和代码
  5. 使用开发的组件
  6. 注意事项

0 人点赞