关于安全:设备指纹系列前端篇

根底篇请看:设施指纹系列–根底篇

咱们接着前文持续写对于设施指纹前端接入方面的内容。话不多说,间接步入正题。

咱们会在下文展现5种前端接入的形式,包含web接入、安卓接入、ios接入、微信小程序接入以及支付宝小程序接入

Web接入

第一步:引入

在页面 HTML 中引入 const-id.js,代码形如:

<script src="https://cdn.dingxiang-inc.com/ctu-group/constid-js/index.js"></script>

因js文件会定期更新,为防止js生效影响您的应用,请不要将js下载到本地服务器上引入

第二步:生成并应用

页面加载后,初始化设施指纹,须要在 JavaScript 中调用 _dx.ConstID(options, callback) 办法获取设施指纹token,代码形如:

var options = {
  appId: '【这里填写 AppID】', // 惟一标识,必填
  server: 'https://constid.dingxiang-inc.com/udid/c1', // constId 服务接口,可选
  userId: '【这里填写 userID】' // 用户标识,可选
};

_dx.ConstID(options, function (err, token) {
  if (err) {
    // console.log('error: ' + err);
    return;
  }
  // console.log('const-id token is ' + token);
});

同时也反对Promise的用法

_dx.ConstID(options).then(function(token) {
  console.log(token)
}).catch(function(err) {
  console.log(err)
})

options 字段阐明

字段 类型 是否必填 阐明
appId String 以后利用的标识
server String constId 服务接口,可选,如不填,则默认会用云服务接口
scene String 场景标识,例如 loginsurvey 等
userId String 业务方的用户惟一标识,例如用户名、用户ID、手机号、Email等
timeout number 超时失败工夫,单位为毫秒
cache boolean 默认为 true,示意会缓存采集后果;改为 false 则每次会从新采集

PC浏览器兼容

浏览器 最低版本
IE 8
Edge 20
Chrome 60
Safari 11
Firefox 60
360 10
Sougou 8
QQ 4

挪动端浏览器兼容

浏览器 最低版本
Chrome 60
UC 12
QQ 8
Safari 11
原生 安卓4.0及以上

安卓接入

一、 环境要求

条目 阐明
开发指标 Android 4.0+
开发环境 Android Studio 3.0.1 或者 Eclipse + ADT
CPU架构 ARM 或者 x86
SDK三方依赖

二、 集成SDK

2.1 下载SDK

点击下载SDK

点击下载demo(仅做代码配置演示应用)

2.2 Android Studio 集成

SDK包集成内容:

  • dx-risk-vx.x.x.aar
2.2.1 把aar文件放到相应模块的libs目录下

Demo工程构造如下

.
├── app
│   ├── build.gradle
│   ├── libs
│   │   └── dx-risk-vx.x.xxr.xxxxxxxx.aar
│   ├── proguard-rules.pro
│   └── src
│       └── main
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
2.2.2 在该Module的build.gradle中如下配置:
android {

  packagingOptions {
      doNotStrip "**/lib*Risk*.so"
  }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])
}

2.3 (可选)增加SDK所需权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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"/>
<uses-permission android:name="android.permission.READ_PHONE_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_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>

2.4 Proguard混同配置

-dontskipnonpubliclibraryclassmembers
-keepattributes *Annotation*,EnclosingMethod

-dontwarn com.dx.mobile.**
-dontwarn *.com.dx.mobile.**
-dontwarn *.com.mobile.strenc.**
-keep class com.dx.mobile.risk.**{*;}
-keep class com.security.inner.**{*;}
-keep class *.com.dx.mobile.**{*;}
-keep class *.com.mobile.strenc.**{*;}

2.5 API 6.0或以上动静权限申请阐明

须要动静申请权限如下:

android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
android.permission.READ_PHONE_STATE
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION

动静申请代码实例(Activity下):

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_demo);

   // API 23或以上的动静申请权限
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       String[] permissionArray = {
               "android.permission.ACCESS_COARSE_LOCATION",
               "android.permission.ACCESS_FINE_LOCATION",
                "android.permission.ACCESS_BACKGROUND_LOCATION",
               "android.permission.WRITE_EXTERNAL_STORAGE",
               "android.permission.READ_EXTERNAL_STORAGE",
               "android.permission.READ_PHONE_STATE",
       };
       this.requestPermissions(permissionArray, 1);
   }

}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
   super.onRequestPermissionsResult(requestCode, permissions, grantResults);
   // start getToken
   new Thread(new Runnable() {
       @Override
       public void run() {
           HashMap<String, String> params = new HashMap<String, String>();
           String token = DXRisk.getToken("appid", params);
       }
   }).start();

}

三. 接口应用阐明

3.1 办法和参数阐明
性能形容

采集端的设施指纹信息,上传至风控后盾,再由风控后盾返回token。 该API为耗时操作,因而必须在非主线程上调用,否则会抛异样。

办法阐明

DXRisk.java 该类是DxRisk SDK的风控组件接口,负责采集本地信息并返回用户前端token。

隐衷采集白名单

自v6.1.18r开始,SDKsetup前,能够调用setAllowPrivacyList进行隐衷采集白名单的设置,默认敞开所有波及隐衷标准红线的采集项

public static void setAllowPrivacyList(long privacyFlag)

应用示例

setAllowPrivacyList(PrivacyFlag.ANDROID_ID); //只采集ANDROID_ID

<!—->

//自定义列表模式
setAllowPrivacyList(PrivacyFlag.X | PrivacyFlag.Y | ...); //示意既采集X又采集Y,X、Y示意具体某项采集的FLAG值,如下表

以下为提供的白名单采集项

FLAG 形容
DEFAULT 默认值,敞开所有隐衷采集项
ALL 关上所有隐衷采集项
IMEI 退出该FLAG则采集手机IMEI值,否则不采集
IMSI 退出该FLAG则采集手机IMSI值,否则不采集
MEID 退出该FLAG则采集手机MEID值,否则不采集
SERIAL\_NUMBER 退出该FLAG则采集手机SERIAL\_NUMBER值,否则不采集
MAC\_ADDRESS 退出该FLAG则采集手机MAC\_ADDRESS值,否则不采集
ICCID 退出该FLAG则采集手机ICCID值,否则不采集
ANDROID\_ID 退出该FLAG则采集手机ANDROID\_ID值,否则不采集
DEVICE\_ID 退出该FLAG则采集手机DEVICE\_ID值,否则不采集
GET\_INSTALLED\_PACKAGES 退出该FLAG则采集手机的利用装置列表,否则不采集
初始化setup

SDK应用前必须调用先setupsetup次要用于数据/环境初始化,个别在ApplicationonCreate下调用:

/**
* 初始化参数,环境
* @param context
* @return
*/
public static boolean setup(Context context)

PS:下列两种形式获取token在网络通顺的状况下没有任何的不同。

惯例Token
/**
 * @return token 通常返回长度为40的字符串。在网络卡顿或不通的状况下,返回4-5k的字符串。
 * @throws DXRiskErrorException 如在主线程调用本API,或者appId为空等等,则会抛出该异样
 */
public static String getToken(String appId, HashMap<String, String> paramsMap) throws DXRiskErrorException
精简Token

获取轻量级Token可获取的设施信息信息远少于getToken(),可能会造成在判断设施是否有危险时呈现较大误差,请审慎应用。

/**
 `* @return token 通常返回长度为40的字符串。在网络卡顿或不通的状况下,返回1k的字符串。
 `* @throws DXRiskErrorException 如在主线程调用本API,或者appId为空等等,则会抛出该异样
 */
public static String getLightToken(String appId, HashMap<String, String> paramsMap) throws DXRiskErrorException

3.2 应用示例

3.2.1 初始化setup

倡议Application.onCreate下调用

@Override
public void onCreate() {
  super.onCreate();    
  // 环境初始化
  DXRisk.setup(this);
}
3.2.2 获取token

整个过程因为是耗时操作,必须要在非主线程上执行,否则会crash

new Thread(){

    @Override
    public void run() {
      /* 私有化配置 */
      HashMap<String, String> params = new HashMap<String, String>();
      // 这里请填写对应的服务端url,留神SAAS和私有化的区别
      params.put(DXRisk.KEY_URL, "https://constid.dingxiang-inc.com");
      // 开启线上数据备份 
      // params.put(DXRisk.KEY_BACKUP, DXRisk.VALUE_ENABLE_BACKUP);
      // 设置申请token超时时长ms,不设置默认为500ms
      params.put(DXRisk.KEY_DELAY_MS_TIME, "2000");
      //此配置敞开SDK缓存,示意每次调用接口都是强制采集信息
      // params.put("PRIVATE_CLEAR_TOKEN", "clear");
      // 开明服务后可在利用治理菜单中获取;私有化版本请填写私有化appId
      String appId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
       // 获取设施指纹token
      final String token = DXRisk.getToken(appId, params);

      // TODO 把token通过Post申请,传到用户后端
  }
}.start();

3.3 异样阐明

在获取token过程中,如果因为网络超时或者加解密失败,该接口有可能会返回为null,同时会输入tag为DXRISK的错误信息,具体形容如下:

DXRISK_REQUEST_NETWORK_ERR            -1001         //网络链接失败
DXRISK_REQUEST_DECRYPT_ERR            -1002         //数据解密谬误
DXRISK_REQUEST_UNCOMPRESS_ERR         -1003         //解压谬误
DXRISK_REQUEST_RESPONSE_EMPTY_ERR     -1004         //返回为空
DXRISK_REQUEST_DATA_PARSE_ERR         -1005         //数据解析失败
DXRISK_REQUEST_DIRTY_DATA_ERR         -1006         //脏数据
DXRISK_CONST_ID_EMPTY                 -1007         //constid为空

ios接入

一、环境需要

条目 阐明
兼容平台 iOS 8.0+
开发环境 XCode 4.0 +
CPU架构 armv7, arm64, i386, x86\_64
SDK依赖 libz, libresolv, libc++ , SystemConfiguration.framework , CoreLocation.framework , CoreTelephony.framework

二、集成SDK

2.1 下载SDK
  • 点击下载集成oc版本demo
  • 点击下载集成swift版本demo

点击下载指纹SDK,SDK的目录构造如下:

  • dx-risk-iOS-x.x.x-xxxxxxx目录 DXRisk sdk

    • DXRisk.framework 不带idfa获取逻辑的Dynamic Library Framework
    • DXRiskWithIDFA.framework 带idfa获取逻辑的Dynamic Library Framework
    • DXRiskStatic.framework 不带idfa获取逻辑的Static Library Framework
    • DXRiskStaticWithIDFA.framework 带idfa获取逻辑的Static Library Framework
2.2 将SDK接入XCode
2.2.1 导入Framework

DXRisk.framework,DXRiskWithIDFA.framework,DXRiskStatic.framework,DXRiskStaticWithIDFA.framework\`其中之一间接拖入工程目录中,或者右击总文件夹增加文件。

  • 如果App中蕴含广告相干的性能,则抉择DXRiskWithIDFA.framework 或者 DXRiskStaticWithIDFA.framework,该版本能够提供更精准的token
  • 如果没有广告,获取idfa可能导致回绝上架,此时请抉择DXRisk.framework 或者 DXRiskStatic.framework
2.2.2 增加FrameWork到工程

若在我的项目中增加DXRisk.framework或者DXRiskWithIDFA.framework其中之一,抉择Target -> General,在Frameworks,Libraries,and Embedded Content中,将DXRisk.framework或者DXRiskWithIDFA.framework 对应的 Embed 切换到Embed & Sign。如下图:

若在我的项目中增加DXRiskStatic.framework或者DXRiskStaticWithIDFA.framework其中之一,须要在Build Settings -> Other Linker Flags 设置 -ObjC 如下图:

2.2.3 配置打包脚本

以下的操作仅限导入DXRisk.framework ,DXRiskWithIDFA.framework动静库

此步骤次要是解决上传Store架构不合乎的问题,如我的项目中已配置过Carthage或有其余相干的打包Framework调整脚本,可略过此步自行调整 抉择Target -> Build Phases,点击+按钮,增加如下脚本:


APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

EXTRACTED_ARCHS=()

for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done

echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"

echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done
2.2.4 权限留神

在iOS 12的环境最好在Capabilities->Access WiFi Information 进行开启操作,这样不便设施指纹数据采集。 

三、接口应用阐明

3.1 办法和参数阐明
// 风控组件:DXRiskManager类
@interface DXRiskManager : NSObject

// 字符串常量
extern NSString* const DXRiskManagerKeyUserId;
extern NSString* const DXRiskManagerKeyEmail;
extern NSString* const DXRiskManagerKeyPhone;
extern NSString* const DXRiskManagerKeyUserExtend1;
extern NSString* const DXRiskManagerKeyUserExtend2;
extern NSString* const DXRiskManagerKeyURL;//私有化服务器地址
extern NSString* const DXRiskManagerKeyBackup;//私有化下应用,将数据备份到顶象服务器(开启为DXRiskManagerKeyBackupEnable 值)
extern NSString* const DXRiskManagerKeyBackupAppId; // 私有化下应用,指定数据备份到顶象服务器的AppId 
  
extern NSString* const DXRiskManagerKeyDegradeNotify;//数据降级告诉,若关上,服务端会有响应的降级统计
extern NSString* const DXRiskManagerKeyCountry;//国家地区设置,默认中国

extern NSString* const DXRiskManagerKeyDelayMsTime; //可填设置申请超时毫秒工夫(默认值为 500 ,范畴是:【100 : 3000】)
// NoticeDegrade参数
/* The NoticeDegrade Value. This value only be used pair with key:DXRiskManagerKeyDegradeNotify to notify token degrade. */
extern NSString* const DXRiskManagerKeyDegradeNotifyEnable;
// Backup参数
/* The Backup Value. This value only be used pair with key:DXRiskManagerKeyBackup to set data backup. */
extern NSString* const DXRiskManagerKeyBackupEnable;
// Country参数
/* The Country Value. This value only be used pair with key:DXRiskManagerKeyCountry to set country. */
extern NSString* const DXRiskManagerCountryChina;
/* The Country Value. This value only be used pair with key:DXRiskManagerKeyCountry to set country. */
extern NSString* const DXRiskManagerCountryIndonesia;

/**
 采集端的设施指纹信息,上传至风控后盾,再由风控后盾返回token。
 该API为耗时操作,因而必须在非主线程上调用。

 @param appId appId   开明服务后可在二级菜单“利用治理”中获取
 @param extendsParams 配置项
 @return token
 */
+ (NSString *)getToken:(NSString *)appId extendParams:(NSDictionary *)extendsParams;

/** 
 DXRiskManager -- 初始化办法
 */
+ (BOOL)setup;  
@end
3.2 应用示例
// 整个过程因为是耗时操作,必须要在非主线程上执行,否则会阻塞UI。如果自身曾经在非UI线程上执行,则不须要另开线程
    dispatch_queue_t dxrisk_queue = dispatch_queue_create("com.dingxiang.dxrisk", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(dxrisk_queue, ^{
        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
        // 依据业务逻辑,填充自定义字段
        [dic setObject:@"123456" forKey:DXRiskManagerKeyUserId];
      
        // 如需设置海内服务器, 可选值请参考头文件字段
        [dic setObject:DXRiskManagerServiceAreaSoutheastAsia forKey:DXRiskManagerKeyServiceArea];
        // 如需自定义服务端URL,填充DXRiskManagerKeyURL字段(私有化部署的状况)
        // 如有须要则增加DXRiskManagerKeyBackup参数,Value固定为DXRiskManagerKeyBackupEnable
        // DXRiskManagerKeyBackupAppId参数可不填,参数为顶象备份数据库提供的备份Appid
        [dic setObject:@"http://xxxxxxx" forKey:DXRiskManagerKeyURL];
        // [dic setObject:DXRiskManagerKeyBackupEnable forKey:DXRiskManagerKeyBackup];
        [dic setObject:@"xxxxxxxxxxxxxxxxxxxx" forKey:DXRiskManagerKeyBackupAppId];
        // 此配置敞开SDK缓存,示意每次调用接口都强制采集信息
        // [dic setObject:@"clear" forKey:@"PRIVATE_CLEAR_TOKEN"];
        
        // 获取token
        // 留神:token最好不要保留在某个局部变量或者字段,每次应用时,都通过API获取。
        BOOL isSuccess = [DXRiskManager setup];
        NSLog(@"setup success: %@" , isSuccess ? @"YES":@"NO");
        NSString *constID = [DXRiskManager getToken:@"xxxxxxxxxxxxxxxxxxxx" extendsParams:dic];
        NSLog(@"constID: %@", constID);
        // TODO 把constid通过Post申请,传到业务后盾。
        // 上面是模仿频繁调用的过程
        while(TRUE) {
            NSLog(@"constID: %@", [DXRiskManager getToken:@"xxxxxxxxxxxxxxxxxxxx" extendsParams:dic]);
            [NSThread sleepForTimeInterval:.5];
        }
    });
3.3 异样阐明

在获取token过程中,如果因为网络超时或者加解密失败,该接口有可能会返回为null,同时会输入tag为DXRISK的错误信息,具体形容如下:

DXRISK_REQUEST_NETWORK_ERR            -1001         //网络链接失败
DXRISK_REQUEST_DECRYPT_ERR            -1002         //数据解密谬误
DXRISK_REQUEST_UNCOMPRESS_ERR         -1003         //解压谬误
DXRISK_REQUEST_RESPONSE_EMPTY_ERR     -1004         //返回为空
DXRISK_REQUEST_DATA_PARSE_ERR         -1005         //数据解析失败
DXRISK_REQUEST_DIRTY_DATA_ERR         -1006         //脏数据
DXRISK_CONST_ID_EMPTY                 -1007         //constid为空

微信小程序接入

js接入

一、下载设施指纹js

SaaS版本下载

私有化版本下载

请留神抉择对应的版本,下载实现后放到本地我的项目中。

二、获取密钥

未注册用户可在顶象官网进行账号注册,创立利用获取利用密钥AppID和AppSecret。

三、应用

  1. 代码接入

<!—->

const ConstId = require('本地设施指纹js寄存门路')
Page({
    onLoad: function () {
      new ConstId({
        appId: '【这里填写在顶象官网申请到的 AppID】', // 惟一标识,必填
        server: 'https://host/udid/w1' // 服务接口地址,请留神私有化客户填写自有域名
      }, (e, id) => {
        if (e) {
          console.log(e)
          return
        }
        console.log('constId:', id)
      })
    }
})
  1. SaaS用户在小程序后盾配置业务域名https://constid.dingxiang-inc.com,私有化用户配置本地部署域名,测试阶段能够开启微信开发者工具右上角详情->本地设置->“不校验域名”。

支付宝小程序接入

接入形式和微信小程序相似,然而应用的SDK不一样。如有须要,请分割客服获取。

const ConstId = require('本地设施指纹js寄存门路')
Page({
    onLoad: function () {
      new ConstId({
        appId: '【这里填写在顶象官网申请到的 AppID】', // 惟一标识,必填
        server: 'https://host/udid/w1' // 服务接口地址,请留神私有化客户填写自有域名
      }, (e, id) => {
        if (e) {
          console.log(e)
          return
        }
        console.log('constId:', id)
      })
    }
})

以上。

如果有设施指纹需要的话,能够返回顶象:收费试用

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理