阿里云设备风险识别 SDK Android 接入 原文标题:SDK Android 接入
内容概要总结
阿里云「设备风险识别 SDK」Android 版接入文档。SDK 需 Android 4.4 及以上(minSdkVersion 19+),支持 arm、armv7、arm64。文档列出所需权限(INTERNET、ACCESS_NETWORK_STATE、READ_PHONE_STATE、WRITE/READ_EXTERNAL_STORAGE)、aar 依赖与 proguard 混淆配置(keep net.security.device.api.*)。核心接口:initWithOptions 用于初始化和信息采集(一次 App 启动只调用一次),options 支持 IPv6 域名上报开关、CustomUrl/CustomHost 指定站点、DataType 采集开关(NO_UNIQUE_DEVICE_DATA 含 OAID、Google 广告 ID、Android ID;NO_IDENTIFY_DEVICE_DATA 含 IMEI、IMSI、SimSerial、BuildSerial(SN)、MAC 地址;还可屏蔽黑灰产 App 列表、局域网 IP、DNS IP、连接的 WIFI 信息等);getDeviceToken 获取客户端 token 并上报业务服务端,再调服务端 API 查询设备风险信息。文档说明 initWithOptions 与 getDeviceToken 调用间隔需 2 秒以上(国际站需 3 秒以上),token 在网络良好时约 600 字节、弱网约 2.5K(国内有网 "Tkxxxx"、弱网 "UFxxxx"),建议传入 bizId 绑定业务 ID 以校验防篡改,并给出完整 Java 代码示例与状态返回值。
原文内容(原文即中文)
本文档介绍了设备风险SDK (Android)的接入流程。
使用须知
设备风险 SDK 需在 Android 4.4 及以上(minSdkVersion 19+)系统上运行。
仅支持 Android 4.4 及以上系统版本的移动智能设备(手机或 Pad)接入。
目前支持 arm、armv7 和 arm64 三个架构。
前提条件
为落实集成第三方 SDK 的隐私合规义务,降低隐私违规风险,请使用阿里云文档中心官网发布的最新版本产品。在使用设备风险识别前,请了解个人信息处理规定及《风险识别 SDK 隐私权政策》,并按照SDK 合规使用说明进行接入。
权限说明
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.READ_PHONE_STATE
该部分权限在 Android 6.0 以上系统中需要动态获取。启用相关权限后,在接入 SDK 并调用initWithOptions初始化接口之前,确保 App 已被授予相关权限。
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
依赖配置
下载Android SDK,并完成解压。SDK 为 Android 标准的.aar 包。
设备风险识别 SDK 内置了较强的代码保护和数据加密机制,因此体积会相对变大。
拷贝解压后的 aar 文件到工程的 libs 目录下,并在 App 的 build.gradle 中添加以下依赖关系:
// 设备风险识别 SDK
implementation files('libs/Android-AliyunDevice-版本号.aar')
接口混淆配置(重要)
如果工程使用了代码混淆,请在 App 工程的 proguard-rules.pro 文件中添加如下配置,防止接口被混淆后功能异常。
- keep class net.security.device.api. {*;}
- dontwarn net.security.device.api.
调用 SDK
获取客户端 Token(getDeviceToken)
1. 初始化(initWithOptions)
该函数用于完成 SDK 初始化和信息采集。在进行风险识别时,需要在满足合规要求的情况下尽可能早地调用。该函数在一次 APP 启动后只需要调用一次。
public interface SecurityInitListener {
// code 表示接口调用状态码
void onInitFinish(int code);
}
public void initWithOptions(Context ctx, String appKey,
Map<String, String> options,
SecurityInitListener securityInitListener);
ctx:当前 Application Context,或 Activity Context。
appKey:用于标识用户身份,可在阿里云控制台的设备 App 管理申请获取。
options:信息采集可选项,默认为 null。可选参数如下。
是否使用 IPv6 域名上报设备信息。0(默认):使用 IPv4 域名。1:使用 IPv6 域名。
设置数据上报服务器域名。指定站点上报时使用,默认不需要设置。
"https://cloudauth-device.aliyuncs.com"
设置数据上报服务器 host。需与 CustomUrl 配对使用,默认和 CustomUrl 一起不需要设置。
"cloudauth-device.aliyuncs.com"
设置不采集设备数据的类型。默认为空(推荐),采集所有数据,具体可配置数据如下表。
单选:NO_UNIQUE_DEVICE_DATA多选:NO_UNIQUE_DEVICE_DATA|NO_IDENTIFY_DEVICE_DATA
包括:OAID、Google 广告 ID、Android ID。
包括:IMEI、IMSI、SimSerial、BuildSerial(SN)、MAC 地址。
包括:黑灰产 App 列表、局域网 IP、DNS IP、连接的 WIFI 信息(SSID、BSSID)、附近 WIFI 列表。
指定站点上报,需要设置 CustomUrl 和 CustomHost 为指定地域,默认情况不需要设置。
CustomUrl:https://cloudauth-device.aliyuncs.com
CustomHost:cloudauth-device.aliyuncs.com
public class CustomApplication extends Application {
// 在阿里云控制台「设备App管理」中创建应用后获取
private static String appKey = "<请在控制台创建应用后获取>";
@Override
public void onCreate() {
super.onCreate();
Map<String, String> options = new HashMap<>();
options.put("IPv6", "0"); // 设置为IPv4,使用IPv6时改为"1"
// 增加隐私数据采集开关,默认不需要配置,如需配置,多选使用|进行或运算,再转成字符串。
// options.put("DataType", String.valueOf(NO_UNIQUE_DEVICE_DATA | NO_IDENTIFY_DEVICE_DATA));
// 设置自定义的数据上报地域(默认不需要设置,仅指定站点时使用)
// options.put("CustomUrl", "https://cloudauth-device.aliyuncs.com");
// options.put("CustomHost", "cloudauth-device.aliyuncs.com");
// 方式一:标准调用(推荐,不关心初始化结果时使用)
SecurityDevice.getInstance().initWithOptions(this, appKey, options, null);
// 方式二:回调调用(需要监听初始化结果时使用)
SecurityDevice.getInstance().initWithOptions(this, appKey, options, new SecurityInitListener() {
@Override
public void onInitFinish(int code) {
if (SecurityCode.SC_SUCCESS != code) {
Log.d("AliyunDeviceRisk", "初始化失败!Code=" + code);
} else {
Log.d("AliyunDeviceRisk", "初始化成功");
}
}
});
}
}
2. 获取客户端 Token(getDeviceToken)
获取客户端 token 并上报到业务服务器,后续通过服务器端服务端API接口接入获取设备风险信息。
确保initWithOptions接口和getDeviceToken接口调用时间间隔 2 秒以上。
调用getDeviceToken时建议传入 bizId,可以将本次 token 和业务唯一 ID 绑定,后在服务端查询结果时将 ID 一起传入,并确保客户端传入 bizId 和服务端传入 ID 一致,可校验 Token 被篡改的风险。
建议在 App非主线程上调用 getDeviceToken 接口,以避免接口调用耗时可能导致的崩溃。
public SecurityToken getDeviceToken();
// 推荐传入,可用于关联业务ID和deviceToken
public SecurityToken getDeviceToken(String bizId)
public class SecurityToken {
// 接口调用状态码
public int code;
// 用于服务器端查询结果的 token 字符串。
public String token;
}
token 字符串在网络环境良好的场景下,长度为 600 字节左右;在网络环境较差的场景下,返回的长度在 2.5K 左右,并且带有特殊标识:
国内:有网"Tkxxxx"、弱网"UFxxxx";
其次,确保 SDK 的initWithOptions接口和getDeviceToken接口调用时间间隔 2 秒以上。
// 建议在非主线程调用,避免阻塞 UI 导致 ANR
new Thread() {
@Override
public void run() {
// 推荐传入 bizId,将 token 与业务 ID 绑定。
// 服务端查询时传入相同 bizId,可校验 token 是否被篡改、替换。
String bizId = "1234567890abcdef1234567890ab";
SecurityToken deviceToken = SecurityDevice.getInstance().getDeviceToken(bizId);
if(null != deviceToken){
if(SecurityCode.SC_SUCCESS == deviceToken.code){
Log.d("AliyunDevice", "token: " + deviceToken.token);
} else {
Log.e("AliyunDevice", "getDeviceToken error, code: " + deviceToken.code);
}
} else {
Log.e("AliyunDevice", "getDeviceToken is null.");
}
}
}.start();
3. 携带 Token 请求服务端
成功获取 deviceToken 后,将 deviceToken 作为参数传至业务服务端。由服务端调用阿里云设备风险识别 API 接口,传入 deviceToken 查询并校验设备风险信息。
状态返回值
SDK 需要的 Android 基础权限未完全授权。
SC_NETWORK_RET_CODE_ERROR
完整代码示例
import net.security.device.api.SecurityDevice;
import net.security.device.api.SecurityInitListener;
import net.security.device.api.SecurityToken;
import net.security.device.api.SecurityCode;
import static net.security.device.api.SecurityDevice.NO_EXTRA_DEVICE_DATA;
public class MainActivity extends AppCompatActivity {
// 在阿里云控制台「设备App管理」中创建应用后获取
private static String appKey = "<请在控制台创建应用后获取>";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
doStandard();
}
private void doStandard() {
// 初始化 SDK,这个是个异步方法
// 在 App 生命周期中只能调用 1 次
// 建议在 Application.onCreate() 中调用
doInit();
// 不建议立即同步调用getDeviceToken,初始化未完成就调用会返回降级的deviceToken
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 步骤二:获取 DeviceToken
// initWithOptions 和 getDeviceToken 调用间隔需 2 秒以上(国际站需 3 秒以上)
// 此处演示在子线程中调用,避免阻塞主线程
new Thread() {
@Override
public void run() {
doGetToken();
}
}.start();
}
/**
* 初始化 SDK,采集设备信息
*/
private void doInit() {
Map<String, String> options = new HashMap<>();
options.put("IPv6", "0"); // 设置为IPv4,使用IPv6时改为"1"
// 增加隐私数据采集开关,默认不需要配置,如需配置,多选使用|进行或运算,再转成字符串。
// options.put("DataType", String.valueOf(NO_UNIQUE_DEVICE_DATA | NO_IDENTIFY_DEVICE_DATA));
SecurityDevice.getInstance().initWithOptions(this, appKey, options, null);
}
/**
* 获取 DeviceToken,建议在非主线程调用
*/
private void doGetToken() {
// 传入 bizId 将 token 与业务 ID 绑定,服务端查询时传入相同 bizId 可校验防篡改
String bizId = "1234567890abcdef1234567890ab";
SecurityToken deviceToken = SecurityDevice.getInstance().getDeviceToken(bizId);
if (null == deviceToken) {
Log.e("AliyunDevice", "deviceToken is null");
} else if (SecurityCode.SC_SUCCESS != deviceToken.code) {
Log.e("AliyunDevice", "获取 token 失败, code: " + deviceToken.code);
} else {
Log.d("AliyunDevice", "获取 token 成功, token: " + deviceToken.token);
// 步骤三:将 deviceToken.token 传至业务服务端,由服务端调用风险识别 API
}
}
}
调用风险识别 API 接口
将 deviceToken 与其他参数,参考服务端API接口接入,请求风险识别 API 接口进行识别。
常见问题
关于设备风控 SDK 的常见问题,请参见SDK常见问题。