服务器端接入

接口通用参数

请求公共参数

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

参数名称类型必须最大长度描述
versionString4接口版本号,当前可用版本为200
secretIdString32秘钥id ,由登录保护服务分配
businessIdString32业务id,由登录保护服务分配
timestampLong10当前 UNIX 时间戳,单位:秒。
nonceString32随机字符串,与 timestamp 联合起来,用于防止重放攻击
signatureString32请求签名,用来验证此次请求的合法性。签名过程和算法参见:签名生成算法。请注意:请将签名转换成小写。

通用响应结果

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

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

响应返回码

返回码返回码描述说明
200ok接口调用状态。
400bad request请求参数错误
401forbidden没权限使用此接口
405param error参数错误
410signature failure签名验证失败
420request expired请求时间戳不正确
430replay attack重放请求
440decode error参数解密失败
450wrong token查询token错误
503service 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.163yun.com/v2/login/check
  • 请求方法:POST
  • 接口说明:登录保护检测
  • 注意事项:建议设置http请求的超时时间,且建议http超时的情况下,认为检测结果为 “正常”。

请求参数

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

参数名称类型必须最大长度描述
tokenString256登录保护结果查询token,由业务前端页面提交给业务后端。
accountString256用户唯一标识,如果是手机号or邮箱,支持传入hash值,hash算法:md5(account)
emailString64用户的邮箱,如果需要加密,支持传入hash值,hash算法:md5(email)
phoneString64默认国内手机号。如有海外手机,需包含国家地区代码,格式为”地区代码-手机号码“。如果需要加密,支持传入hash值,使用MD5算法对1开头,11位纯数字手机号进行加密后的值,32位小写,hash算法:md5(phone)
ipString20用户参加活动时的ip
registerTimeNumber13用户的注册时间,单位:秒
registerIpString20用户的注册IP
extDataString2048额外信息,建议自己构造json结构

响应结果

  • 参数说明

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

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

识别为正常的响应结果:

{
    "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.163yun.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工具类参见点击查看详情
Online Chat Tel:95163223