美文网首页
Python Flask 实现通过 safari 获取 iOS设

Python Flask 实现通过 safari 获取 iOS设

作者: 不知道是哪个号 | 来源:发表于2019-09-27 16:28 被阅读0次

    原文地址

    相关名词及简介

    名称 iOS描述 Android描述
    UDID (Unique Device Identifier) 设备的唯一标识符,在iOS5之前,获取设备唯一标识都是采用UDID,iOS6苹果废弃了该方法,提供了IDFA 用来标示设备的唯一标识符。该UDID是获取UUID后,写入.so文件生成。即使APP重装,值也不变,除非root手机(普通用户做不到)
    IDFA (Identifier For Advertising) 广告标识符,1.iOS6面世,广告标示符是由系统存储,同一个设备上的所有App都会取到相同的值,是苹果专门给各广告提供商用来追踪用户的。 2.用户可以限制广告跟踪 3.系统重置或者设置中还原广告标识符会重置
    IDFV (Identifier For Vendor) 应用开发商标识符,通过CFBundleIdentifier(DNS反转格式)的前两部分生成。例如:com.text.one和com.text.two得到的IDFV是一样的。如果用户将属于此开发商的所有应用卸载,则IDFV的值会被重置。
    UUID (Universally Unique Identifier) 通用唯一识别码,目前最广泛应用的 UUID,是微软公司的全局唯一标识符GUIDs。 UUID每次生成的值都是唯一且不一样的。iOS可以通过结合钥匙串来区别应用唯一性 同iOS
    IMEI (International Mobile Equipment Identity) 国际移动设备身份码的缩写。是由15位数字组成的“电子串号”,它与每台手机一一对应,每个IMEI在世界上都是唯一的,写在主板上,重装APP不会改变。iOS5之后被禁止。 GSM设备返回的,并且是写在主板上的,重装APP不会改变IMEI。Android 6.0以上系统需要用户授予read_phone_state权限,如果用户拒绝就无法获得。
    Mac地址(Media/Medium Access Control) 硬件标识符,包括WiFi mac地址和蓝牙mac地址。iOS7之后被禁用(同时禁用的还有OpenUDID) 硬件标识符,包括WiFi mac地址和蓝牙mac地址。Android 6.0之后被禁止,若获取则会被判定为有害应用
    OpenUDID 在UDID被禁用后的一个开源方案,原理是利用剪贴板在同一设备上的不同应用间共享一个OpenUDID,iOS7对剪贴板进行了限制,功能被废掉了。

    在iOS5之后,iOS为了获取设备的UDID,苹果提供了利用Safari的方式。

    创建类型为 xml 的文件(ep:mobileconfig.xml)并配置以下参数

    ⚠️ 接收数据的接口地址 该地址用来接收并解析客户端返回的xml数据

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <key>PayloadContent</key>
            <dict>
                <key>URL</key>
                <!--接收数据的接口地址-->
                <string>http://172.50.10.152:5000/app/parse_udid</string>
                <key>DeviceAttributes</key>
                <array>
                    <string>UDID</string>
                    <string>IMEI</string>
                    <string>ICCID</string>
                    <string>VERSION</string>
                    <string>PRODUCT</string>
                </array>
            </dict>
            <key>PayloadOrganization</key>
            <!--组织名称-->
            <string>com.dev.org</string>
            <key>PayloadDisplayName</key>
            <!--文件标题-->
            <string>查询设备UDID</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadUUID</key>
            <!--随机生成的唯一GUID字符串-->
            <string>29313601-7007-474f-b916-e0bac0f94fed</string>
            <key>PayloadIdentifier</key>
            <string>com.dev.text</string>
            <key>PayloadDescription</key>
            <!--文件描述-->
            <string>本描述文件仅用来获取设备的UDID</string>
            <key>PayloadType</key>
            <string>Profile Service</string>
        </dict>
    </plist>
    

    最终显示的配置文件如下所示

    Python 模块

    UDID xml数据解析

    该接口地址对应 mobileconfig.xml 文件中服务端接收解析数据的地址,解析完成之后重定向到结果页面

    @main.route('/app/parse_udid', methods=['GET', 'POST'])
    def parse_udid():
         """解析获取udid数据"""
        b_data = request.data
        data_str = str(b_data).split('<?xml')[-1].split('</plist>')[0]
        data_str = '<?xml{}</plist>'.format(data_str).replace('\\t', '').replace('\\n', '')
        soup = BeautifulSoup(data_str, features='xml')
        xml = soup.find('dict')
        keys = []
        values = []
        for item in xml.find_all():
            if item.name == 'key':
                keys.append(item.text)
            else:
                values.append(item.text)
        print(keys)
        print(values)
        return redirect(url_for('main.udid', u_id=values[-2]), code=301)
    
    

    ⚠️需要使用301重定向,否则会提示描述文件安装失败

    UDID 获取和结果展示

    1. udid 不存在时显示获取udid按钮
    2. udid 存在且不为0是显示udid结果
    3. udid 为0时下载配置文件(注意Content-Type配置

    python接口模块

    @main.route('/app/udid', methods=['GET', 'POST'])
    @main.route('/app/udid/<u_id>', methods=['GET', 'POST'])
    def udid(u_id=None):
        """1.udid下载页面"""
        if not u_id:
            return render_template('udid.html', udid='')
        
         """2.udid结果显示"""
        if u_id != '0' and u_id != 0:
            return render_template('udid.html', udid=u_id)
    
         """3.udid配置文件下载"""
        def file_content(file_path):
            with open(file_path, 'rb') as f:
                return f.readlines()
    
        file_path = basedir + '/app/static/mobileconfig.xml'
        filename = os.path.basename(file_path)
        response = Response(file_content(file_path))
        response.headers['Content-Type'] = 'application/x-apple-aspen-config; chatset=utf-8'
        response.headers['Content-Disposition'] = 'attachment;filename="{}"'.format(filename)
        return response
    

    页面配置模块

    {% extends "bootstrap/base.html" %}
    {% block title %} 设备信息 {% endblock %}
    
    {% block page_content %}
        {% if udid %}
            <h3>UDID:  {{ udid }}</h3>
        {% else %}
            <a class="buttons" href="/app/udid/0" target="_blank">点击获取您的UDID</a>
        {% endif %}
    {% endblock %}
    

    以上内容参考以下文章:

    Apple ConfigurationProfileExamples

    iOS-UDID-Safari

    iphone-ota-setup-with-signed-mobileconfig

    Create GUIDs online

    相关文章

      网友评论

          本文标题:Python Flask 实现通过 safari 获取 iOS设

          本文链接:https://www.haomeiwen.com/subject/tkifsctx.html