后端接入

2022.07.11 11:06:57

    规范说明

    通信协议

    HTTPS 协议。

    请求方法

    网易易盾提供的所有接口,均支持 POST/GET 方法。当参数名与参数值拼装起来的 URL 长度小于 1024 个字符时,可以用GET发起请求;当参数类型含 byte[] 类型或拼装好的请求URL过长时,必须用 POST 发起请求。建议所有API调用都使用 POST 方法请求。

    当前仅支持post请求的Content-Type: application/x-www-form-urlencoded格式,不支持application/json。

    字符编码

    所有接口的请求和响应数据编码皆为 utf-8。

    API请求结构

    名称 描述 备注
    API入口 具体API接口地址 https://ac.dun.163.com/v3/common/check
    公共参数 每个接口都包含的通用参数 详见 公共参数 说明
    私有参数 每个接口特有的参数 详见每个API接口定义

    公共参数

    请求公共参数

    易盾营销反作弊服务的所有接口均包含这些公共参数。

    参数名称 类型 必须 最大长度 描述
    version String 4 接口版本号,当前可用版本为300
    secretId String 32 秘钥id ,由营销反作弊服务分配
    businessId String 32 业务id,由营销反作弊服务分配
    timestamp Long 13 请求当前 UNIX 时间戳(毫秒单位),请注意服务器时间是否同步
    nonce String 32 随机字符串,与 timestamp 联合起来,用于防止重放攻击
    signature String 32 请求签名,用来验证此次请求的合法性。签名过程和算法参见:签名生成算法。请注意:请将签名转换成小写。

    通用响应结果

    所有接口响应均采用json格式,如无特殊说明,每次请求的返回值都包含如下字段:

    参数名称 类型 描述
    code int 接口调用状态,取值参见:响应返回码。
    msg String 结果说明,如果调用出错,返回错误描述
    result Object 接口返回结果,具体参见各接口说明。

    响应返回码

    返回码 返回码描述 说明
    200 ok 接口调用状态。
    400 bad request 请求参数错误
    401 forbidden 没权限使用此接口
    405 param error 参数错误
    410 signature failure 签名验证失败
    420 request expired 请求时间戳不正确
    430 replay attack 重放请求
    440 decode error 参数解密失败
    450 wrong token 查询token错误
    503 service unavailable 服务器内部出现异常

    接口鉴权

    • 申请安全凭证

    在第一次使用 API 之前,需申请安全凭证,安全凭证包括 SecretId 和 SecretKey ,SecretId 是用于标识 API 调用者的身份,SecretKey 是用于加密签名字符串和服务器端验证签名字符串的密钥。SecretKey 必须严格保管,避免泄露。

    • 签名生成算法

    签名过程:

    • 参数排序:对所有请求参数(不包括 signature 参数),按照参数名ASCII码表升序顺序排序。如:foo=1, bar=2, foobar=3, baz=4 排序后的顺序是 bar=2, baz=4, foo=1, foobar=3 。
    • 拼接参数:将排序好的参数名和参数值构造成字符串,格式为:key1+value1+key2+value2… 。根据上面的示例得到的构造结果为:bar2baz4foo1foobar3。
    • 拼接KEY:选择与 secretId 配对的 secretKey ,加到上一步构造好的参数字符串之后,如 secretKey=6308afb129ea00301bd7c79621d07591 ,则最后的参数字符串为 bar2baz4foo1foobar36308afb129ea00301bd7c79621d07591 。
    • 签名HASH:把上一步骤拼装好的字符串采用 utf-8 编码,使用 MD5 算法对字符串进行摘要,计算得到 signature 参数值,将其加入到接口请求参数中即可。MD5 是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32位十六进制字符。

    示例代码

    /**
     * 生成签名信息
     * @param secretKey 产品私钥
     * @param params 接口请求参数名和参数值map,不包括signature参数名
     * @return
     */
    public static String genSignature(String secretKey, Map<String, String> params) {
    if (secretKey == null || params == null || params.size() == 0) {
        		return "";
        }
        // 1. 参数名按照ASCII码表升序排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        // 2. 按照排序拼接参数名与参数值
        StringBuffer paramBuffer = new StringBuffer();
        for (String key : keys) {
            paramBuffer.append(key).append(params.get(key) == null ? "" : params.get(key));
        }
        // 3. 将secretKey拼接到最后
        paramBuffer.append(secretKey);
        // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。
        return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8"));
    }
    

    反作弊check接口

    • 接口地址:https://ac.dun.163.com/v3/common/check
    • 请求方法:POST
    • 接口说明:反作弊检测
    • 注意事项:建议设置http请求的超时时间,且建议http超时的情况下,认为检测结果为 “正常”。

    请求参数

    公共参数已省略,详细见:请求公共参数,其他参数如下:

    参数名称 类型 必须 最大长度 描述
    token String 256 反作弊结果查询token,由业务前端页面提交给业务后端。
    account String 256 用户唯一标识,如果是手机号or邮箱,支持传入hash值,hash算法:md5(account)
    email String 64 用户的邮箱,如果需要加密,支持传入hash值,hash算法:md5(email)
    phone String 64 默认国内手机号。如有海外手机,需包含国家地区代码,格式为“+447410xxx186(+44即为国家码)”。如果需要加密,支持传入hash值,hash算法:md5(phone)
    ip String 20 用户参加活动时的ip
    registerTime Number 13 用户的注册时间,单位:毫秒
    registerIp String 20 用户的注册IP
    nickname String 256 用户的昵称
    userLevel String 32 用户的等级
    activityId String 256 活动的唯一标识
    target String 256 活动操作的目标,比如:A给B点赞,则target为B。如果target是手机号或邮箱,请提供hash值,hash算法:md5(target)
    extData String 2048 额外信息,建议自己构造json结构

    反作弊响应结果

    • 参数说明

    响应字段如下,通用响应字段已省略,详细参见:通用响应结果。

    参数名 类型 描述
    action int 检测结果:0 正常(放行),10 正常(观察),20 致命(拦截)
    taskId String 任务id,与检测请求一一对应,建议保存此值方便以后数据查询
    hitInfos List 命中信息,例如:[{"hitType":5,"hitTypeDesc":"校验异常","hitMsg":"无SDK数据"}],
    其中hitType类型为int,含义是命中类型,详见下方“hitType返回码及含义”表,
    hitTypeDesc类型为String,含义为命中类型的中文描述,
    hitMsg类型为String,含义是命中详情,内容可能为空.
    如果同时命中多个类型,则会返回所有风险信息。正常情况下,action为 0(正常)时,hitInfos 中不会有信息。
    • hitType返回码及含义
    hitType值 含义描述
    0 正常
    1 数据异常,主要表现有数据完整性校验不通过或数据伪造等
    2 行为异常,主要表现有用户的操作行为(鼠标点击/移动等)无法通过行为验证模型等
    3 设备模型,主要表现有设备指纹等信息无法通过设备验证模型等
    4 业务模型,主要表现有撞库、批量操作、违反业务规则等
    5 校验异常,主要表现有数据强校验结果异常或数据伪造等
    6 模拟器,主要表现有安卓端使用手机模拟器的行为
    7 越狱或ROOT,主要表现有iOS系统已越狱或Android系统已root
    8 浏览器异常,主要表现有浏览器分辨率等参数异常或遭篡改等
    9 IP异常,主要表现有终端IP画像结果为风险IP或高危IP等
    10 黑名单,易盾自有及客户自定义黑名单数据
    11 白名单,易盾自有及客户自定义白名单数据
    12 高危账号,主要表现有团伙账号或异常共享账号等风险账号类型
    13 多开小号,主要表现有批量多开
    14 篡改硬件信息,主要表现为篡改硬件设备参数信息
    15 篡改系统信息,主要表现为篡改系统参数信息
    16 高危设备,主要表现为高危设备画像风险评分,黑产特征设备等类型
    17 群控或云控,主要表现为群控工作室设备或云机
    18 使用修改工具,主要表现有使用Hook修改、Xposed修改,Magisk修改等
    19 虚拟环境,非真实设备访问环境,区别于安卓模拟器,如编辑后台等
    20 脚本工具,黑灰产用于作弊行为的脚本工具
    • 响应结果示例

    反作弊识别为正常的响应结果:

    {
        "code":200,
        "msg":"ok",
        "result":{
            "action":0,
            "taskId":"698256a52215495ab3c61f14e8e6e844",
            "hitInfos":[
                {
                }]
        }
    }
    

    反作弊识别为作弊的响应结果:

    {
        "code":200,
        "msg":"ok",
        "result":{
            "action":20,
            "taskId":"5aecbc658f2e4cfab24b6f4171e5839e",
            "hitInfos":[
                {
                    "hitType":5,
    		"hitTypeDesc":"校验异常",
                    "hitMsg":"正式定制版在这个字段会返回命中详情"
                },
                {
                    "hitType":6,
    	        "hitTypeDesc":"模拟器",
                    "hitMsg":"正式定制版在这个字段会返回命中详情"
                }
            ]//如果同时命中多个类型,则会返回所有风险信息
        }
    }
    

    设备指纹结果

    设备指纹结果默认不返回,若有需要请联系易盾策略运营开通。

    响应字段如下,通用响应字段已省略,详细参见:通用响应结果。

    参数名 类型 描述
    taskId String 任务id,与检测请求一一对应,建议保存此值方便以后数据查询
    detail Json 设备信息详情,字段解释见设备指纹字段表
     ∟deviceData Json 设备信息详情,字段解释见设备指纹字段表
    • iOS/Android 返回字段
    参数名 类型 描述 终端
    deviceId String 设备唯一指纹 iOS、Android
    osv String 系统版本 iOS、Android
    model String 手机厂商 iOS、Android
    appVersion String APP版本号 iOS、Android
    simulator int 是否模拟器(0:不是模拟器,非0:是模拟器) iOS、Android
    root int 是否root(0:不是root,1:是root) iOS、Android
    flag int 是否被调试(0:没有被调试,非0:被调试) iOS、Android
    isInjection Boolean 是否注入 iOS、Android
    mac String mac地址 Android
    • web/h5 返回字段
    参数名 类型 描述 终端
    deviceId String 设备唯一指纹 web/h5
    appVersion String 浏览器版本信息 web/h5

    设备指纹识响应结果:

    {
        "code":200,
        "msg":"ok",
        "result":{
            "action":0,
            "taskId":"698256a52215495ab3c61f14e8e6e844",
            "hitInfos":[
                ],
            "detail": {
    		"deviceData": {
    			"appVersion": "1.0",
    			"osv": "6.0",
    			"simulator": 2,
    			"flag": 0,
    			"root": 1,
    			"model": "M55 Note",
    			"isInjection": false,
    			"deviceId": "41c75882d231afec0dbf2d54d18c66df",
    			"mac": "a4:49:d1:e4:6d:d7"
    		}
    	}
        }
    }
    

    完整示例代码

    public class AnticheatProtectionChecker {
    
        /** 产品密钥ID,产品标识 */
        private static final String SECRET_ID = "your secret id";
    
        /** 产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露 */
        private static final String SECRET_KEY = "your secret key";
    
        /** 业务ID,易盾根据产品业务特点分配 */
        private static final String BUSINESS_ID = "your business id";
    
        /** 易盾反作弊检测接口地址 */
        private static final String API_URL = "https://ac.dun.163.com/v3/common/check";
    
        /** 实例化HttpClient,发送http请求使用,可根据需要自行调参 */
        private static final HttpClient httpClient = HttpClient4Utils.createHttpClient(100, 20, 1000, 1000, 1000);
    
        public static void main(String[] args) throws Exception {
    
            String token = "9ca17ae2e6ffcda170e2e6ee95c13ba8888aa6ee4df2b3fe8af241f59d9e8dc15eb3bcafd9b84ba1ebacbaef2af0feaec3b92a87abafb2f64e82bfb995e65387ae00d0bc50ac9b9a91cd5cb8bda697fb72839bee9e";
            String account = "100002";
            String email = "zhangsanzuiniu@163.com";
            String phone = "18888888888";
            String loginIp = "123.123.123.120";
            String registerTime = "1479178545";
            String registerIp = "123.123.123.123";
            String activityId = "168168";
            String target = "100003";
            String nickname = "yidun";
            String userLevel = "level1";
    
            Map<String, String> params = new HashMap<String, String>();
            params.put("version", "300");
            params.put("secretId", SECRET_ID);
            params.put("businessId", BUSINESS_ID);
            params.put("timestamp", System.currentTimeMillis() / 1000 + "");
            params.put("nonce", Math.random() + "");
            params.put("token", token);
    
            params.put("account", account);
            // 对邮箱取md5
            params.put("email", md5(email));
            // 对手机号取md5
            params.put("phone", md5(phone));
            params.put("ip", loginIp);
            params.put("registerTime", registerTime);
            params.put("registerIp", registerIp);
            params.put("activityId", activityId);
            params.put("target", target);
            params.put("nickname", nickname);
            params.put("userLevel", userLevel);
    
            // 生成签名,参见签名过程的示例代码
            params.put("signature", SignatureUtils.genSignature(SECRET_KEY, params));
    
            // 发送check请求,业务方可以选择自己熟悉的工具包发送请求
            // 请特别注意,调用接口时,请设置http超时时间
            // 建议http超时的情况下,认为识别结果为“正常”
            String response = HttpClient4Utils.sendPost(httpClient, API_URL, params, Consts.UTF_8);
            try {
                // 解析响应
                JsonObject jObject = new JsonParser()
    .parse(response).getAsJsonObject();
                int code = jObject.get("code").getAsInt();
                String msg = jObject.get("msg").getAsString();
                if (code == 200) {
                    JsonObject dataObject = jObject.getAsJsonObject("result");
                    int action = dataObject.get("action").getAsInt();
                    if (action == 0) {
                        System.out.println("正常(放行)");
                    } else if (action == 10) {
                        System.out.println("正常(观察)");
                    } else if (action == 20) {
                        System.out.println("致命(拦截)");
                    }
                } else {
                    System.out.println(String.format("ERROR: code=%d, msg=%s", code, msg));
                }
            } catch (Exception e) {
                System.out.println("接口调用异常(超时 等),当作[正常]处理");
    
                e.printStackTrace();
            }
        }
    }
    
    • 备注:示例代码中的HttpClient4Utils、SignatureUtils工具类参见点击查看详情
    在线咨询 电话咨询:95163223 免费试用