数美设备指纹 SDK(即 'smsdk')最低支持 API Level 14。

1 工程配置#

本章节为 Android Studio 工程配置步骤,其他 IDE 开发者,如 IntelliJ IDEA、Eclipse 等,需要自行根据本节描述进行转换。跨平台配置,如 Flutter、uniapp、unity3d 等,可以自行增加插件进行接入,也可以联系我们提供对应插件 Demo。

  1. 将 smsdk*.aar 拷贝到 Module(例如 app 模块) 的 libs 目录下

  2. 在 build.gradle 添加 aar 引用

    android {
    ……
    defaultConfig {
    ……
    ndk {
    // 选择实际需要的 cpu 架构
    abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
    }
    }
    }
    dependencies {
    implementation fileTree(dir: "libs", include: ["smsdk*.aar"])
    ...
    }
  3. 声明权限,在 AndroidManifest.xml 中添加如下权限

    <!-- 必选权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!-- 建议权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    权限作用

    权限作用
    INTERNET(必选)将采集数据通过网络发送到服务器
    ACCESS_NETWORK_STATE(必选)判断网络是否连接;
    获取 network (网络连接状态)信息,如 2g, 3g, 4g, wifi 等,运营商信息
    ACCESS_COARSE_LOCATION获取 cell (基站)信息
    ACCESS_FINE_LOCATION获取 cell (基站)信息
    ACCESS_WIFI_STATE获取 bssid(wifi mac), ssid 信息
    WRITE_EXTERNAL_STORAGE写入 SD 卡数美设备标识
    READ_EXTERNAL_STORAGE读取存储在 SD 卡中的数美设备标识
  4. http 设置,smsdk 默认使用 http 请求,在 targetSdkVersion > 27 时, 需在 AndroidManifest.xml 中增加如下配置

    <application
    ......
    android:usesCleartextTraffic="true"
    ......
    >
    ......
    </application>

    如果 application 节点有设置 android:networkSecurityConfig 属性,如

    <application
    ......
    android:usesCleartextTraffic="true"
    android:networkSecurityConfig="@xml/network_security_config"
    ......>
    ......
    </application>

    则需要向 xml/network_security_config.xml 文件中添加 smsdk 域名配置(代理或私有化模式需要添加对应域名)

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
    <!-- smsdk 域名配置 -->
    <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">fengkongcloud.com</domain>
    </domain-config>
    </network-security-config>
  5. 代码放混淆

    向 proguard-rules.pro 文件中添加 smsdk 防混淆规则,如下

    -keep class com.ishumei.** {*;}

2 标准接入#

smsdk 是数美风控体系中的终端,主要功能包括采集设备信息和生成设备标识。当产品需要对相关业务进行风控分析时,可以通过 SmAntiFraud 类的 create 方法进行风控。调用 create 方法会立即采集设备信息,所以 必须 在同意隐私政策后且需要风控的场景下调用 create 方法,避免引起非合理场景采集不必要信息问题。

create 方法的使用方式如下所示:

// smsdk 参数对象
SmAntiFraud.SmOption option = new SmAntiFraud.SmOption();
// 必填,组织标识
option.setOrganization("YOUR_ORGANIZATION");
// 必填,应用标识,登录数美后台应用管理查看,没有合适值,可以写 "default"
option.setAppId("YOUR_APP_ID");
// 必填,加密 KEY,邮件中 android_public_key 附件内容
option.setPublicKey("YOUR_PUBLICK_KEY");
// 选填,通过此方式屏蔽部分数据采集,此处以 oaid 为例,其他可控字段见合规指南《可控配置项 -> Android 端》
Set<String> notCollect = new HashSet<>();
notCollect.add("oaid"); // 标识不采集 oaid
option.setNotCollect(notCollect);
// 采集设备数据
boolean isOk = SmAntiFraud.create(context, option);
SmOption 方法参数类型是否必填默认值说明
setOrganizationString数美分配的公司标识,数美后台可以查看
setAppIdStringdefault应用标识,区分不同应用,数美后台可以查看
setPublicKeyString公钥标识,开通账号发送邮件中publicKey项
setUrlString代理模式、私有化模式中设置设备数据上报地址
setConfUrlString代理模式、私有化模式中设置云配信息获取地址
setCloudConfbooleantrue是否启用云配功能,如果设置为 flase,则不会发起云网络请求
setAreaStringSmAntiFraud.AREA_BJ标准模式中,设置数据上报请求区域,有如下值:
AREA_BJ:业务在国内(默认值)
AREA_XJP:业务在东南亚
AREA_FJNY:业务在欧美
setNotCollectSet<String>屏蔽部分采集字段

风控场景下调用 create 方法时,smsdk 会检查传入参数是否合法,如果返回值为 false,则需要过滤 logcat 日志中的 Smlog 进行自检,注意 smsdk 3.3.0 之前版本没有返回值。

create 方法采集数据大约需要 1 秒(低端机型会出现超出 2 秒情况),采集过程发生在子线程,不会阻塞当前线程。调用 create 方法返回 true 后,可调用 SmAntiFraud.getDeviceId() 方法获取标识。

获取标识时机:触发需要风控的业务事件时使用,比如登录、注册等关键事件中上报 getDeviceId 返回的字符串。

部分开发者将 getDeviceId 放到所有网络请求的 Header 中,这样做会出现一些问题,需要开发者配合处理,原因及方案将参照 smsdk 时序图进行说明

smsdk-flow

场景一:调用 create 方法后,smsdk 缓存中有 boxId,如图 ”7. 应用事件“,此时调用 getDeviceId 会立即返回 boxId,可以将 boxId 直接放到业务请求 Header 中。此场景一般出现在调用 create 方法时,smsdk 已经完成过一次服务交互,从服务器获取到 boxId 并缓存成功。

场景二:调用 create 方法后,smsdk 缓存中没有 boxId 但是有 boxData,如图 ”9. 应用事件“,此时调用 getDeviceId 会立即返回 boxData,由于 boxData 长度较长,直接存放在业务请求 Header 中可能会出现 4K 限制,导致 boxData 被截断,处理方案见下文。此场景一般出现在调用 getDeviceId 方法时,smsdk 采集完成后,生成 boxData,但是未完成一次服务交互,未能将 boxData 更新为 boxId。

场景三:调用 create 方法后,smsdk 缓存中没有 boxId 且没有 boxData,如图中 "12. 应用事件"。此时调用 getDeviceId 方法会等待采集完成,并将采集数据加密生成 boxData 返回,等待过程与采集速度和 create 时机有关,假设采集耗时为 2 秒,若调用 create 后立即调用 getDeviceId,那么 getDeviceId 方法会阻塞当前线程 2 秒;若调用 create 1 秒后调用 getDeviceId 方法,getDeviceId 会阻塞当前线程 1 秒,需要开发者确保不会由于阻塞造成 ANR。此处同样有 boxData 被截断的问题。此场景一般出现在调用 create 方法后,smsdk 缓存中没有 boxId 且 smsdk 正在采集中时调用 getDeviceId 方法。

场景二和场景三所述 boxData 截断问题解决方案:与业务端同学协调,调整业务请求 Header 长度限制,建议调整到 24KB 大小;如果业务侧无法修改可以通过配置 smsdk 进行 boxData 长度调整,此方法会降低 boxData 安全性,请作为备选方案执行

option.usingShortBoxData(true);

场景三中所述阻塞问题解决方案:不要在启动SDK时立即调用 getDeviceId 方法,建议延迟 1 到 2 秒调用,如果需要在最早时机调用,可以使用回调方式监听 boxId

// 此方法必须在 create 方法之前调用,否则可能会出现不触发回调问题
SmAntiFraud.registerServerIdCallback(new SmAntiFraud.IServerSmidCallback() {
@Override
public void onSuccess(String boxId) {
// 服务器下发成功或缓存中有可用 boxId
// 如果缓存中存在 boxId,此方法会触发 2 次,第 2 次会更新缓存中的 boxId
}
@Override
public void onError(int errCode) {
// 错误码含义见下表
// 触发此方法后,可以通过 SmAntiFraud.getDeviceId() 获取 boxId 或者 boxData,建议在子线程中调用 SmAntiFraud.getDeviceId() 方法。
}
});
errCode含义
-1无网络,常见原因:设备无网络
-2网络异常,网络连接异常(conn.getResponseCode() 抛出异常)或者 http 状态非 200,常见原因:代理或私有化服务器配置错误
-3业务异常,下发业务状态码非 1100,服务器未返回 deviceId,常见原因:参数配置错误、qps 超限、服务器异常
-4其他异常

boxId 与 boxData 无法直接当做设备标识,但是可以使用 boxId 或 boxData 直接查询设备风险。

至此 smsdk 国内标准接入部分已经全部完成,如果没有定制化需求,此时已经接入完毕,建议参考 "测试" 章节自查是否接入成功。

海外标准接入(由于数据合规要求,所有海外接入都需要走代理模式,此处为无法提供代理服务的特殊客户使用),需要使用海外专用包,并切换设备指纹机房,设置如下

  1. 业务机房在欧美(弗吉尼亚机房)

    // 用户分布范围为欧美
    option.setArea(SmAntiFraud.AREA_FJNY);
    // 用户分布范围为全球,则需要开启加速功能,配置如下
    // option.setArea(SmAntiFraud.AREA_FJNY);
    // String host = "http://fp-na-it-acc.fengkongcloud.com";
    // option.setUrl(host + "/deviceprofile/v4");
    // option.setConfUrl(host + "/v3/cloudconf");
  2. 业务机房在欧美(法兰克福机房)

    option.setArea("flkf");
    String host = "http://api-device-eur.fengkongcloud.com";
    option.setUrl(host + "/deviceprofile/v4");
    option.setConfUrl(host + "/v3/cloudconf");
  3. 业务机房在东南亚(新加坡机房)

    // 用户分布范围为东南亚
    option.setArea(SmAntiFraud.AREA_XJP)
    // 用户分布范围为全球,则需要开启加速功能,配置如下
    // option.setArea(SmAntiFraud.AREA_XJP);
    // String host = "http://fp-sa-it-acc.fengkongcloud.com";
    // option.setUrl(host + "/deviceprofile/v4");
    // option.setConfUrl(host + "/v3/cloudconf");

3 私有化接入#

主要步骤与标准接入类似,需要增加以下配置

// 设置 area,此值为组织标识
option.setArea("YOUR-ORGANIZATION");
// 设置私有地址,将 private-host 替换为私有化的主机名(域名)
String host = "https://private-host";
option.setUrl(host + "/deviceprofile/v4"); // 示例路径,需要与真实场景一致
option.setConfUrl(host + "/v3/cloudconf"); // 示例路径,需要与真实场景一致

注意,如果传入 host 为 http 请求,如 http://private-host,需要确保 APP 可以发送 http 请求,参考 "工程配置" 章节 http 设置部分。私有化接入完成后,需要根据 "测试" 章节进行自测检查。

4 代理接入#

开发者需要自行搭建代理服务器,SDK 端上逻辑设置与标准接入类似,需要增加以下配置

// 设置私有地址,将 host 替换为代理服务器的主机名(域名)
String host = "https://proxy-host";
option.setUrl(host + "/deviceprofile/v4"); // 示例路径,需要与真实场景一致
option.setConfUrl(host + "/v3/cloudconf"); // 示例路径,需要与真实场景一致

5 测试#

  1. 调用 SmAntiFraud.create(context, option) 方法获取返回值为 true
  2. 调用 SmAntiFraud.getDeviceId() 方法返回值为 boxId,如 Bm21V93t5QwTNdwyQxxxxxRYuSnOuwwylqZvz8Lixxxxx17lRMqcQ1jz9RwN6qW31/Z0YYmxN8KQnrya9xxxxxx==
  3. 执行 adb logcat | grep Smlog 无异常输出,若有异常输出,请根据提示修改
  4. 通过数美管理后台导航栏选择 ”设备风险趋势",找到 “设备详情” 部分,查看是否有数据上报(可能存在延时,一般不超过 30 分钟)
  5. 无法通过测试时,联系数美工作人员进行排查

6 SDK 升级#

本文适用于 Android smsdk v2 版本升级到 Android smsdk v3 版本,希望已接入客户尽快切换到 smsdk v3 版本。

升级步骤及注意事项

  1. 删除旧版本 smsdk,请根据 SmAntiFraud 类所在位置,定位 smsdk 包进行删除,如果项目中包含 libsmsdk.so 动态库,需要一并删除
  2. 根据 ”Android SDK 工程配置“ 章节步骤接入新版本 smsdk
  3. 新版本中删除了部分 API,替换包后,导致编译失败,直接将 smsdk 报错方法删除即可
  4. 运行新 smsdk,根据 ”Android SDK 测试“ 章节进行自测,如果不成功,请根据错误提示进行修改或联系数美工作人员进行排查
  5. 代理接入客户,需要根据 ”解密工具及代理服务器说明 代理接入“ 章节进行代理服务器升级
  6. 私有化接入客户,需要联系数美工作人员进行整体升级

smsdk v3 版本终端不再提供明文设备标识,业务端不可以将 boxId 或 boxData 直接当做标识,获取标识方法参考 ”解密工具及代理服务器说明 设备指纹标识解密“。

smsdk v3 版本首次启动直接调用 SmAntiFraud.getDeviceId 方法会出现阻塞当前线程问题,解决方案查看 ”Android SDK 标准接入 场景三“ 小节。

在线咨询