服务器端接入

2020.06.08 14:34:08

    接口通用参数

    请求公共参数

    易盾登录保护服务的所有接口均包含这些公共参数。

    参数名称 类型 必须 最大长度 描述
    version String 4 接口版本号,当前可用版本为200
    secretId String 32 秘钥id ,由登录保护服务分配
    businessId String 32 业务id,由登录保护服务分配
    timestamp Long 10 当前 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, foo_bar=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/v2/login/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 默认国内手机号。如有海外手机,需包含国家地区代码,格式为”地区代码-手机号码“。如果需要加密,支持传入hash值,使用MD5算法对1开头,11位纯数字手机号进行加密后的值,32位小写,hash算法:md5(phone)
    ip String 20 用户参加活动时的ip
    registerTime Number 13 用户的注册时间,单位:秒
    registerIp String 20 用户的注册IP
    extData String 2048 额外信息,建议自己构造json结构

    响应结果

    • 参数说明

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

    参数名 类型 描述
    action int 检测结果,取值如下:0 正常,10 嫌疑,20 致命
    hitType int 命中类型,取值如下:0:正常,1:数据异常(数据完整性校验不通过或数据伪造等),2:行为异常(用户的操作行为(鼠标点击/移动等)无法通过行为验证模型等),3:设备模型(设备指纹等信息无法通过设备验证模型等),4:业务模型(撞库、批量操作、违反业务规则、自定义白名单等),5:校验异常(数据强校验结果异常或数据伪造等),6:模拟器(安卓端使用手机模拟器的行为),7:越狱或ROOT(iOS系统已越狱或Android系统已root),8:浏览器异常(浏览器分辨率等参数异常或遭篡改等),9:IP异常(终端IP画像结果为风险IP或高危IP等),10:黑名单(易盾自有及用户自定义黑名单数据)
    taskId string 任务id,与检测请求一一对应
    hitMsg string 命中详情,开通正式定制版后支持返回,可定制返回值
    • 响应结果示例

    识别为正常的响应结果:

    {
        "code":200,
        "msg":"ok",
        "result":{
            	"action":0,
            	"hitType":0,
            	"taskId":"12345678900987654321123456789009"
        }
    }
    

    识别为作弊的响应结果:

    {
        "code":200,
        "msg":"ok",
        "result":{
            	"action":20,
            	"hitType":4,
            	"hitMsg":"正式定制版在这个字段会返回命中详情",
            	"taskId":"12345678900987654321123456789000"
        }
    }
    

    示例代码

    public class LoginProtectionChecker {
    
        /** 产品密钥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/v2/login/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";
    
            Map<String, String> params = new HashMap<String, String>();
            params.put("version", "200");
            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("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 免费试用