Taro开发记录 - Taro3+React 解决小程序用户隐私保护授权

1,018 阅读3分钟

背景

8 月 10 日微信官方发布《关于小程序隐私保护指引设置的公告》-- 为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者,微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则后,方可调用微信提供的隐私接口。于是便有了一下记录 现在社区上 专门Taro3+React 解决小程序用户隐私保护授权的资料偏少 贡献点绵薄之力

思路

根据微信官方提供的 demo 决定使用在首页处理隐私弹窗逻辑即 demo1 (Taro 方案)官方片段

 在app的onLaunch 使用wx.getPrivacySetting 获取隐私授权信息
 若需要授权  通过ReactDOM.render方法将隐私协议组件插入到页面根元素中
 使用 wx.openPrivacyContract 接口打开隐私保护指引页面
 用户点击“拒绝”直接关闭小程序(wx.exitMiniProgram),用户点击“同意”同步给微信,关闭弹窗;

注意事項

  1. app.config.js  中配置__usePrivacyCheck__: true,
  2. 基础版本库 使用 3.0.0 以上
  3. taro 暂时还没有适配bindagreeprivacyauthorization 按钮方法 需要使用@tarojs/plugin-inject 自行适配

参考资料

1. 借鉴了这个大佬的 ReactDOM.render 插入的思路

juejin.cn/post/727274…

2. 借鉴了这个大佬的样式和思路

juejin.cn/post/727230…

实现

  1. 入口文件配置
// src/app.js
// 这里是Functional Component 
import React, { useEffect } from 'react'
import { usePrivacy } from '@/utils/usePrivacy';


// 全局样式
import './app.css'

const store = configStore()

function App(props) {
   // 隐私协议检测
   usePrivacy();
   return (
     // 在入口组件不会渲染任何内容,但我们可以在这里做类似于状态管理的事情
     <Provider store={store}>
       {/* props.children 是将要被渲染的页面 */}
       {props.children}
     </Provider>
   )
}


/*************这里是Class Component**************/

class App extends Component {
   // 对应 onLaunch
   onLaunch() {
         把usePrivacy中的useLaunch方法复制到这里就行了
   }

   render() {
     // 在入口组件不会渲染任何内容,但我们可以在这里做类似于状态管理的事情
     return (
       <Provider store={store}>
         {/* this.props.children 是将要被渲染的页面 */}
         {this.props.children}
       </Provider>
     )
   }
}


export default App

  1. hooks 实现 具体看代码注释

      // usePrivacy.js
      import Taro, { useLaunch } from '@tarojs/taro';
      import ReactDOM from 'react-dom';
      import Privacy from '../../components/Privacy/Privacy';
    
      export const usePrivacy = () => {
      useLaunch(() => {
        // 在onLaunch 使用Taro.getPrivacySetting 获取隐私授权信息
          if (Taro.getPrivacySetting) {
              Taro.getPrivacySetting({
                  success: (res) => {
                      console.log('是否需要授权:', res.needAuthorization, '隐私协议的名称为:', res.privacyContractName);
                      const portalId = 'privacyPortal';
                      const currentPages = Taro.getCurrentPages();
                      const currentPage = currentPages[currentPages.length - 1];
                      const root = document.getElementById(currentPage?.$taroPath);
                     let portal = document.getElementById(portalId);
    
                     if (!portal) {
                         portal = document.createElement('view');
                         portal.id = portalId;
                     }
    
                     if (root && res.needAuthorization) {
                         root.appendChild(portal);
                         const onClose = () => {
                            // 通过ReactDOM.unmountComponentAtNode卸载组件
                             ReactDOM.unmountComponentAtNode(portal);
                         };
                        // 通过ReactDOM.render方法将隐私协议组件插入到页面根元素中
                         ReactDOM.render(<Privacy onClose={onClose} privacyInformation={res} />, portal);
                     }
                 },
                 fail: () => {},
                 complete: () => {},
             });
         } else {
             // 低版本基础库不支持 wx.getPrivacySetting 接口,隐私接口可以直接调用
             console.log('低版本无需隐私接口');
         }
         });
      };
    
  2. Privacy 组件开发

注意使用 Button 中的onAgreePrivacyAuthorization 需要通过@tarojs/plugin-inject 处理不然不生效

# 1.安装@tarojs/plugin-inject(taro3.1以上) 注意版本号和自己的 taro 主版本号保持一致
npm i @tarojs/plugin-inject -D

# 2.config/index.js 中增加 plugins 配置:
{
  ... 其他配置
   plugins:[
      [
        "@tarojs/plugin-inject",
        {

          components: {
            Button: {
              bindagreeprivacyauthorization: "" // 这个必须要写,不然不触发回调
            }
          }
        }
      ]
    ]
}

Privacy 实现 就是调用 API 了  样式的话 用了这个大佬的

juejin.cn/post/727230…

// Privacy.js
import Taro from '@tarojs/taro';
import { Text, View } from '@tarojs/components';
import { Button } from '@nutui/nutui-react-taro';
import cn from 'classnames';
import style from './index.module.scss';

const Privacy = ({ onClose, privacyInformation }) => {
    const { privacyContractName } = privacyInformation;
    const onCancel = () => {
        onClose();
        Taro.exitMiniProgram({ success: (res) => {} });
    };

    return (
        <View className={style.privacy}>
            <View className={style.content}>
                <View className={style.title}>隐私保护指引</View>
                <View className={style.des}>
                    在使用当前小程序服务之前,请仔细阅读
                    <Text
                        onClick={() => {
                            Taro.openPrivacyContract({
                                fail: () => {
                                    Taro.showToast({
                                        title: '遇到错误',
                                        icon: 'error',
                                    });
                                },
                            });
                        }}
                        className={style.link}
                    >
                        {privacyContractName}
                    </Text>
                    。如你同意{privacyContractName},请点击“同意”开始使用。
                </View>
                <View className={style.btns}>
                    <Button onClick={onCancel} className={cn([style.item, style.reject])}>
                        拒绝
                    </Button>
                    <Button
                        id="agree-btn"
                        className={cn([style.item, style.agree])}
                        openType="agreePrivacyAuthorization"
                        {/*注意目前taro暂时没有兼容 一定要使用@tarojs/plugin-inject处理*/}
                        onAgreePrivacyAuthorization={() => {
                            onClose();
                        }}
                    >
                        同意
                    </Button>
                </View>
            </View>
        </View>
    );
};
export default Privacy;

結尾

以上就是 我这次开发简单的记录了  希望能够帮到你