Python Flask 实现通过 safari 获取 iOS设

2019-09-27  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读