首先了解官方提供demo:
demo1: 演示使用 wx.getPrivacySetting 和 <button open-type="agreePrivacyAuthorization"> 在首页处理隐私弹窗逻辑 https://developers.weixin.qq.com/s/gi71sGm67hK0
demo2: 演示使用 wx.onNeedPrivacyAuthorization 和 <button open-type="agreePrivacyAuthorization"> 在多个页面处理隐私弹窗逻辑,同时演示了如何处理多个隐私接口同时调用。 https://developers.weixin.qq.com/s/4X7yyGmQ7EKp
demo3: 演示 wx.onNeedPrivacyAuthorization、wx.requirePrivacyAuthorize、<button open-type="agreePrivacyAuthorization"> 和 <input type="nickname"> 组件如何结合使用 https://developers.weixin.qq.com/s/jX7xWGmA7UKa
demo4: 演示使用 wx.onNeedPrivacyAuthorization 和 <button open-type="agreePrivacyAuthorization"> 在多个 tabBar 页面处理隐私弹窗逻辑。 https://developers.weixin.qq.com/s/g6BWZGmt7XK9
- 小程序后台隐私协议添加对应隐私协议(例如:剪贴板、手机号授权等)协议更新后有一定时间的缓存才能测试(大概是在半天之后可以测试)优先处理添加协议 (如果之前小程序已经添加过对应的协议,则需要重新提交审核同步信息才会返回正常用来测试)
- 基础库设置3.23.3及以上 (微信版本:iOS 8.0.36、安卓 8.0.35会携带此基础库版本)
- app.json文件内这个配置__usePrivacyCheck__属性为true (uniapp开发参考下图)
- 开发工具清除全部缓存之后重新编译、手机微信下拉删除最近小程序等进行隐私协议同步信息获取测试
二、关于小程序隐私保护指引设置的公告
为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者, 微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则后,方可调用微信提供的隐私接口。 开发者首先需确定小程序是否涉及处理用户个人信息,如涉及,则需配置用户隐私授权弹窗, 且仅有在平台《小程序用户隐私保护指引》中声明了所处理的用户个人信息,才可以调用平台提供的对应接口或组件。
三、设置《小程序用户隐私保护指引》
四、填写《小程序用户隐私保护指引》
只有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将无法调用成功。
五、配置用户隐私授权弹窗 (触发方式:隐私API、组件)
1.了解隐私协议所需相关API
01.wx.requirePrivacyAuthorize() 用于模拟隐私接口调用
02.wx.openPrivacyContract() 用于打开下面封装好隐私弹框中的隐私协议
03.wx.onNeedPrivacyAuthorization() 用于监听用户是否吊起相关的隐私协议
04.wx.getPrivacySetting() 用于查询微信侧记录用户隐私协议状态
基本流程为:03 -----> 04 -----> 02
2.封装微信侧用户隐私协议状态
//获取微信侧同步的用户隐私协议开关
function getPrivacySetting(callback){if(wx.getPrivacySetting){wx.getPrivacySetting({success: result => {console.log(result,"同步信息结果") // 返回结果为: result = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }if (result.needAuthorization) {// 需要弹出隐私协议console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理")callback && callback(result);} else {console.log("获取微信储存的用户协议同步信息-用户已同意,请忽略")}},fail: () => {},complete: () => {}})}
}
3.封装隐私协议弹框放置全局组件中
全局组件-wxml
<van-popup show="{{privacyFlag}}" z-index="{{99999}}" catch:touchstart="" position="center" bind:close="onCloseDoctorInfo" close-on-click-overlay="{{false}}" custom-style="width:80%; border-radius:20rpx;" ><view class="followFrame customStyle"><view class="followFrame-title">用户隐私保护提示</view><view class="followFrame-cont"><view class="followFrame-cont-text big">亲爱的用户,感谢您的信任!您使用本小程序提供的产品服务前应当阅读并同意</view><view class="followFrame-cont-text links" bindtap="openPrivacyContract">{{urlTitle}}</view><view class="followFrame-cont-text">当您点击同意并开始使用产品服务时,即表示你已理解并同息该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用本小程序提供的相关产品及服务。 </view></view><view class="followFrame-bom"><view class="followFrame-bom-box flex-row-around-start"><button id="disagree-btn" bindtap="handleDisagree" class="followFrame-bom-btns flex1">不同意</button><button id="agree-btn" bindagreeprivacyauthorization="handleAgree" open-type="agreePrivacyAuthorization" class="followFrame-bom-btns active flex1">同意</button></view></view></view></van-popup>
全局组件-JS
JS//引入相关模块
const { getPrivacySetting } = require("../utils/utils")
//设置协议回调、关闭回调数组变量
let privacyHandler
let privacyResolves = new Set()
let closeOtherPagePopUpHooks = new Set()
//注册并监听隐私API调用
if (wx.onNeedPrivacyAuthorization) {wx.onNeedPrivacyAuthorization(resolve => {//获取用户微信侧同步结果getPrivacySetting(result=>{console.log(result,"同步信息结果") // 返回结果为: result = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }if (result.needAuthorization) {// 需要弹出隐私协议if (typeof privacyHandler === 'function') privacyHandler(resolve,result)console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理-页面")}})})
}
//处理关闭页面其他弹框
const closeOtherPagePopUp = (closePopUp) => {closeOtherPagePopUpHooks.forEach(hook => {if (closePopUp !== hook) {hook()}})
}
Component({options: {styleIsolation: 'shared',multipleSlots: true},data: {urlTitle: "",privacyFlag: false,height: 0,},lifetimes: {attached: function() {const closePopUp = () => {this.disPopUp()}privacyHandler = (resolve,result) => {this.setUrlTitle(result);console.log(result,"999999")privacyResolves.add(resolve)this.popUp()// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗closeOtherPagePopUp(closePopUp)}closeOtherPagePopUpHooks.add(closePopUp)this.closePopUp = closePopUp},detached: function() {closeOtherPagePopUpHooks.delete(this.closePopUp)}},methods: {//处理隐私弹框内展示的隐私协议标题setUrlTitle(result){this.setData({urlTitle:result.privacyContractName})},//用户同意相关协议handleAgree(e) {this.disPopUp()// 这里演示了同时调用多个wx隐私接口时要如何处理:让隐私弹窗保持单例,
点击一次同意按钮即可让所有pending中的wx隐私接口继续执行 (看page/index/index中的 wx.getClipboardData 和 wx.startCompass)privacyResolves.forEach(resolve => {resolve({event: 'agree',buttonId: 'agree-btn'})})privacyResolves.clear()this.triggerEvent('handleAgree', {result:true});},//用户拒绝相关协议handleDisagree(e) {this.disPopUp()privacyResolves.forEach(resolve => {resolve({event: 'disagree',})})privacyResolves.clear()this.triggerEvent('handleAgree', {result:true});},//打开隐私弹框popUp() {if (this.data.privacyFlag === false) {this.setData({privacyFlag: true})}},//关闭隐私弹框disPopUp() {if (this.data.privacyFlag === true) {this.setData({privacyFlag: false})}},//打开微信提供的小程序侧隐私协议openPrivacyContract() {wx.openPrivacyContract({success: res => {console.log('openPrivacyContract success')},fail: res => {console.error('openPrivacyContract fail', res)}})},checkPrivacyStatus() {let that = this;getPrivacySetting(result=>{if (result.needAuthorization) {that.setUrlTitle(result);that.popUp();} else {console.log("微信侧已记录用户同意");}})}}
})
父组件监听全局隐私弹框时间回调
父组件-wxml<privacy-popup id="privacyPop" bindhandleAgree="handleAgree"></privacy-popup>父组件-JS//隐私协议弹框按钮回调handleAgree(event){let that = this;console.log(event);let {result} = event.detail;// result 根据用户选择可处理后续相关逻辑true 用户同意相关隐私 例如:因昵称组件弹出的框 为true之后就可将昵称组件设置为聚焦状态false 用户拒绝 例如:音视频组件 用户拒绝之后可返回上级页面、继续弹框进行处理等},
4.app.json中引入全局组件:
"privacy-popup": "/components/privacyPopup"
5.全局使用(隐私弹框)
全局隐私弹框相关代码如下:
首页wxml引入组件<privacy-popup id="privacyPop"></privacy-popup>首页onReady时触发检测隐私弹框逻辑that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").checkPrivacyStatus();
6.按需使用(隐私弹框)进入单个隐私页面时优先检测(手机号授权API触发隐私弹框)
6-1.1.引入全局组件到手机号授权页面:<privacy-popup id="privacyPop"></privacy-popup>
6-1.2.页面onReady的时候开始检测:that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").checkPrivacyStatus();
6-2.1.在用户点击按钮即将吊起隐私弹框时使用如下代码:getPrivacySetting(result=>{if (result.needAuthorization) {// 需要弹出隐私协议that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").setUrlTitle(result);console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理")} else {console.log("获取微信储存的用户协议同步信息-用户已同意,请忽略")//走隐私允许之后的逻辑}})
特别说明:wx.authorize这个API在测试的时候并不会触发监听隐私弹框逻辑 跟微信文档有些出入,如果涉及到该API 可以使用6-2.1方式进行处理具体逻辑如下
1.先从微信侧获取用户隐私状态
2.根据状态处理不同的逻辑
2.1用户未同意则弹框提示
2.2用户已同意就可以调用wx.authorizeAPI或者走之后的隐私接口调用啦
六、清空历史同步状态
1.微信下拉---最近---最近使用的小程序
2.开发工具---清除模拟器缓存---清除全部数据/授权数据
七、常见错误说明
- { "errMsg": "A:fail api scope is not declared in the privacy agreement", "errno": 112 } 使用到了 A 隐私接口,但是开发者未在[mp后台-设置-服务内容声明-用户隐私保护指引]中声明收集 A 接口对应的隐私类型。
- 还有个114的忘记统计是啥原因了
八、微信文档指引:
用户隐私保护指引填写说明:用户隐私保护指引填写说明 | 微信开放文档
小程序用户隐私保护指引内容介绍:小程序用户隐私保护指引内容介绍 | 微信开放文档
小程序隐私协议开发指南:小程序隐私协议开发指南 | 微信开放文档