服务端接入

OpenAPI 接口文档

通过OpenAPI查询反外挂详情数据,满足多场景的业务需求。

通用设置

  • 通信协议

支持HTTP协议,HTTPS协议

  • 请求方法

Post方法

  • 字符编码

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

  • API请求结构
名称描述备注
API入口具体API接口地址http://open-yb.163yun.com/api/open/v1/risk/doubtful/checkroleidexist
公共参数每个接口都包含的通用参数详见 公共参数 说明
私有参数每个接口特有的参数详见每个API接口定义
  • 公共参数

公共参数是用于标识产品和接口鉴权目的的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,每次请求均需要携带这些参数。

  • 鉴权参数
鉴权参数名称类型是否必填最大长度描述
appIdString10appId
timestamplong13调用接口当前时间,单位毫秒,防重放
nonceString16随机码,防重放
tokenString32使用appKey签名的数据,检验权限
  • 响应通用字段

Json 格式, 如无特殊说明,每次请求的返回值中,都包含下面字段:

参数名称类型描述
codeint接口调用状态,200:正常,其他值:调用出错,返回码见响应返回码定义
msgString结果说明,成功返回ok,调用出错,那么返回错误描述见响应返回码定义
dataJSON返回结果,构成如下
lastestEventTimelong不为默认值0时为当前可供查询数据的最新时间

注意:嫌疑数据明细查询返回格式比较特殊,请具体接口定义。

  • 响应返回码

响应返回码(code)反应了API 调用和执行的概要结果。当返回码不为 200 时, 表示请求未正常执行,返回码描述 (msg) 对该结果进行了细化补充,用户可根据返回码判断 API 的执行情况。

所有接口调用返回值均包含 code 和 msg 字段, code 为返回码值,msg 为返回码描述信息,返回码表如下:

200OK正常
400BAD_REQUEST请求参数不合法
4400API_REQ_PARA_MISSING参数appId缺失
401API_REQ_UNAUTHORIZED未授权或者授权已过期
402OFFLINE服务下线
403FORBIDDEN无权限操作
404API_NOT_FOUND服务不存在
405LENGTH_OVERLIMIT长度超过限制
406ENTITY_TOO_LARGE请求实体数据大小超过限制!
407REQUEST_EXPIRED请求过期
411CAPCITY_EXCEED请求频率或数量超过限制!
500SERVICE_UNAVAILABLE服务异常
501SERVICE_FAILED操作失败
5503API_NOT_AVAILABLEAPI未开放,不可使用
5509API_QPS_LIMIT_EXCEEDAPI QPS超出限制
5709API_APP_FREQ_MIN_LIMIT_EXCEEDAPI 最小请求频率超出限制,需要降低请求频率
  • 接口鉴权

易盾移动安全服务使用签名方法对接口进行鉴权,所有接口每一次请求都需要包含签名信息(signature 参数),以验证用户身份,防止信息被恶意篡改。

1.申请安全凭证

在第一次使用 API 之前,需申请安全凭证,Appkey,请妥善保管,避免泄漏。

2.签名生成算法

签名生成方法如下:

a.对公有参数,按照参数名ASCII码表升序顺序排序。如:foo=1, bar=2, foo_bar=3, baz=4 排序后的顺序是 bar=2, baz=4, foo=1, foobar=3。

b.将排序好的参数名和参数值构造成字符串,格式为:key1+value1+key2+value2… 。根据上面的示例得到的构造结果为:bar2baz4foo1foobar3 。

c.选择申请的Appkey,加到上一步构造好的参数字符串之后。

d.把c步骤拼装好的字符串采用 utf-8 编码,使用 MD5 算法对字符串进行摘要,计算得到 signature 参数值,将其加入到接口请求参数中即可。MD5 是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32位十六进制字符。

获取签名Token示例代码如下:

String token= SignatureUtils.genSignature(appKey, appId, timestamp, nonce);

附带SignatureUtils.java 如下:

package com.netease.is.clientapi.utils;
import com.google.common.collect.Maps;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Map;
/**
* Created by yubaohong on 19-5-22.
*/
public class SignatureUtils {
     /**
     * 暴露获取token的方法
     * @param appKey
     * @param appId
     * @param timestamp
     * @param nonce
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String genSignature(String appKey, String appId, String timestamp, String nonce) throws UnsupportedEncodingException {
        Map<String, String>userParams = getTokenParams(appId, timestamp, nonce);
        return SignatureUtils.genSignature(appKey, userParams);
    }
    
     /**
     * 生成签名信息
     * @param appKey产品私钥
     * @param params 接口请求参数名和参数值map,不包括signature参数名
     * @return
     */
    private static String genSignature(String appKey, Map<String, String> params) throws UnsupportedEncodingException {
        // 1. 参数名按照ASCII码表升序排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        // 2. 按照排序拼接参数名与参数值
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append(key).append(params.get(key));
        }
        // 3. 将appKey拼接到最后
        sb.append(appKey);
        // 4. MD5是128位长度的摘要算法,转换为十六进制之后长度为32字符
        return DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
    }
    
    /**
     * 拼接参数
     * @param appId
     * @param timestamp
     * @param nonce
     * @return
     */
    private static Map<String, String> getTokenParams(String appId, String timestamp, String nonce) {
        <String, String> userParams = Maps.newHashMap();
        userParams.put("appId", appId);// 固定
        userParams.put("timestamp", timestamp);
        userParams.put("nonce", nonce);
        return userParams;
    }
}

嫌疑数据明细查询

注意事项:因取证信息场景复杂,为了保障封号依据完备,如需封号,建议结合角色的业务数据进行二次判断或者 和易盾技术人员进行二次确认,以确保准确无误 ;控制接口调用频率,频率过高,可能会超过频率限制,导致查询失败,建议间隔10s。

接口地址:http://open-yb.163yun.com/api/open/v1/risk/detail_data/list

请求方法:Post

接口描述:风险详情数据下载

时间范围:支持历史嫌疑数据明细查询

Content-Type:application/json

请求参数,由鉴权参数与请求参数两部分构成:

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

参数名称类型是否必填最大长度描述
duplicateint不去重:1,去重查询:0
queryTimeTypeint0:使用客户端上报时间(默认);1:使用入库时间
beginDateTimelong开始时间,单位毫秒
endDateTimelong结束时间,单位毫秒
startFlagString第一次为"",后续查询需要用前一次查询的返回的startFlag来填充

请求参数示例:

{"appId":"A008513561","timestamp":${currentTime},"token":"${sign}","nonce":"111","duplicate":1,"beginDateTime":1564041324000,"endDateTime":1574127724519,"startFlag":""}

响应结果:

调用正常返回使用linedText格式

响应内容设置:Content-type: text/plain;charset=utf-8

linedText格式定义如下:

行号格式描述
第1行startFlag=${下一批数据起始标记}1. 当查询需要分批返回数据时,表示下一批数据起始标记。2. 当为null值,表示数据都已经返回,不需要继续执行下一批查询
第2行separator=${列分隔符号}行中的不同列之间分隔符,如Tab,或\001等
第3行colums=${数据列名称}数据列名称,以"列分隔符"切分
第4行size=${总行数}数据总行数,可以为空值
第5行每行数据记录数据记录,从第5行开始
第...行......

返回示例如下:

startFlag=949f4284bb294e7c840cc535143fc5a6
separator=\t
colums=设备ID	Android版本	角色ID	账号	角色名称	服务器	包名	APP版本号	游戏版本	资源文件版本	IP	外挂检测	风险检测	应用环境检	入库时间	传输方式
size=160
3ZUYOV1XDZ	7.0.0	roleTestid1	roleaccount1	cthtest1	roleservern1	[com.tujia.hotel]	1.1.1	123.58.160.153	加速器	盗版	正常	2019-07-30 09:57:24	客户端直传
1SF7L9RHI2	7.0.0	roleTestid1	roleaccount1	cthtest1	roleservern1	[com.tujia.hotel]	1.1.1	123.58.160.153	加速器	盗版	正常	2019-07-30 09:57:25	客户端直传

异常返回Json格式,构成如下:

参数名称类型描述
codeint接口调用状态,200:正常,其他值:调用出错,返回码见响应返回码定义
msgString结果说明,成功返回ok,调用出错,那么返回错误描述见响应返回码定义

示例如下:

{
"code": 4401,
"msg": "Token验证失败"
}

检查roleId是否存在服务

注意事项:因取证信息场景复杂,为了保障封号依据完备,如需封号,建议结合角色的业务数据进行二次判断或者 和易盾技术人员进行二次确认,以确保准确无误 ;控制接口调用频率,频率过高,可能会超过频率限制,导致查询失败,建议间隔10s。

接口地址:http://open-yb.163yun.com/api/open/v1/risk/doubtful/checkroleidexist

请求方法:post

接口描述:检查roleId是否存在,支持批量

时间范围:支持一周内数据查询

Content-Type:application/json

请求参数,由鉴权参数与请求参数两部分构成:

公共参数已省略,详细见 请求公共参数

请求参数定义如下:

参数名称类型是否必填最大长度描述
beginTimelong开始时间,单位毫秒
endTimelong结束时间,单位毫秒
roleIdsString 数组数组最大个数:100

请求参数示例:

{
   "appId": "A003614194",
    "timestamp": ${currentTime},
    "nonce":111,
    "token": "${sign}",
    "roleIds":  ["roleTestid","roleTestid2","TransTest"],
    "beginTime":1575388800000,
    "endTime": 1585545601000
}

响应结果:

调用正常返回使用JSON格式

构成如下:

参数名称类型描述
codeint接口调用状态,200:正常,其他值:调用出错,返回码见响应返回码定义
msgString结果说明,成功返回ok,调用出错,那么返回错误描述见响应返回码定义
dataJSON返回结果,构成如下
lastestEventTimelong不为默认值0时为当前可供查询数据的最新时间
参数名称类型描述
totalint返回记录条数,去重
roleIdsJSON 数组记录明细

完整示例如下:

有数据时:

{
    "code": 0,
     "msg": null,
     "data": {
        "total": 2,
        "roleIds": [
            "TransTest",
            "roleTestid"
        ]
    },
 "lastestEventTime": 0
}

无数据时:

 {

    "code": 0,
    "msg":"当前查询条件无数据返回,可能因为数据不存在或者数据处理未完成,可供查询数据的最新时间见lastestEventTime字段。",
    "data": {
        "total": 0,
        "roleIds": []
    },
   "lastestEventTime": 1578366604897
}

​ 此结果说明数据处理存在延时或者数据不存在,可进一步确定是何种情况,设置查询的 endTime 小于 lastestEventTime,如果此时依然没有数据说明数据不存在,自动封禁有风险操 作请谨慎,建议综合参考其它因素。

透传接口文档

易盾智能反外挂透传接口,适用于恶意屏蔽反外挂IP和域名从而绕过反外挂服务的情况,反外挂服务透过游戏方服务器的中转与易盾安全实验室建立连接,易盾安全实验室的最新策略可顺利更新到游戏移动端。

透传方案

  • 在游戏方部署(或使用已有)Nginx代理转发服务器
  • 易盾反外挂SDK,使用游戏方的域名,将数据上报到代理服务器,再转发给易盾服务器

image title

实施部署

  • 安装Nginx(可以使用已有Nginx服务)
  • 配置Nginx conf/nginx.conf ,完整配置,见附录的 nginx.conf ,
    • 请联系 易盾反外挂开发对接人 ,根据游戏服务器部署区域,选用对应的配置文件: 新加坡 ,或 香港 ,或 杭州 的Nginx配置
    • 如果使用新安装Nginx,配置直接复制附录的 nginx.conf
    • 如果使用已有Nginx,反向代理配置参考 server 部分,如图,具体见附录! image title
  • 申请域名,例如:ydt.somegame.com,根据Nginx配置,绑定到Nginx 80 端口(见附录Nginx配置)

联调验证

  • 将申请的透传域名,告知<易盾反外挂开发对接人>
  • 测试透传链路是否正常: 客户端发起请求 --> 透传代理服务器 --> 易盾数据接收服务

附录

  • 附1 新加坡 Nginx.conf 配置
worker_processes  4;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
    accept_mutex off;
}

http {
    include mime.types;
    default_type application/octet-stream;

    
    sendfile on;
    tcp_nopush on;

    keepalive_timeout 5;
    tcp_nodelay on;

    gzip on;
    gzip_http_version 1.0;
    gzip_proxied any;
    gzip_types application/javascript application/x-javascript application/xml application/atom+xml text/css text/plain text/xml text/x-component text/javascript application/json;
    gzip_vary on;

    server_name_in_redirect off;

    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-From-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;


    proxy_hide_header ETag;
    proxy_hide_header Via;
    proxy_hide_header X-Cache;
    proxy_hide_header X-Img-From;
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Squid-Error;
    proxy_hide_header X-Varnish;

    proxy_buffering off;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    proxy_intercept_errors on;

    proxy_connect_timeout 10;

    client_header_buffer_size 8k;
    client_max_body_size 64m;
    map_hash_bucket_size 64;
    types_hash_bucket_size 64;
    server_names_hash_bucket_size 256;
    server_names_hash_max_size 2048;
    variables_hash_bucket_size 128;

    server_tokens off;

    server {
        listen 80;

        location / {
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host "xjp-yb.dun.163.com";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Isctc-Mode "tc-xjp";
            proxy_pass http://xjp-yb.dun.163.com;
        }
    }   
}

  • 附2 杭州 Nginx.conf 配置
worker_processes  4;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
    accept_mutex off;
}

http {
    include mime.types;
    default_type application/octet-stream;

    
    sendfile on;
    tcp_nopush on;

    keepalive_timeout 5;
    tcp_nodelay on;

    gzip on;
    gzip_http_version 1.0;
    gzip_proxied any;
    gzip_types application/javascript application/x-javascript application/xml application/atom+xml text/css text/plain text/xml text/x-component text/javascript application/json;
    gzip_vary on;

    server_name_in_redirect off;

    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-From-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_hide_header ETag;
    proxy_hide_header Via;
    proxy_hide_header X-Cache;
    proxy_hide_header X-Img-From;
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Squid-Error;
    proxy_hide_header X-Varnish;

    proxy_buffering off;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    proxy_intercept_errors on;

    proxy_connect_timeout 10;

    client_header_buffer_size 8k;
    client_max_body_size 64m;
    map_hash_bucket_size 64;
    types_hash_bucket_size 64;
    server_names_hash_bucket_size 256;
    server_names_hash_max_size 2048;
    variables_hash_bucket_size 128;

    server_tokens off;

    server {
        listen 80;

        location / {
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host "yb.dun.163.com";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Isctc-Mode "tc-yb";
            proxy_pass http://yb.dun.163.com;
        }
    }
   
}
  • 附3 香港 Nginx.conf 配置
worker_processes  4;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
    accept_mutex off;
}

http {
    include mime.types;
    default_type application/octet-stream;

    
    sendfile on;
    tcp_nopush on;

    keepalive_timeout 5;
    tcp_nodelay on;

    gzip on;
    gzip_http_version 1.0;
    gzip_proxied any;
    gzip_types application/javascript application/x-javascript application/xml application/atom+xml text/css text/plain text/xml text/x-component text/javascript application/json;
    gzip_vary on;

    server_name_in_redirect off;

    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-From-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_hide_header ETag;
    proxy_hide_header Via;
    proxy_hide_header X-Cache;
    proxy_hide_header X-Img-From;
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Squid-Error;
    proxy_hide_header X-Varnish;

    proxy_buffering off;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    proxy_intercept_errors on;

    proxy_connect_timeout 10;

    client_header_buffer_size 8k;
    client_max_body_size 64m;
    map_hash_bucket_size 64;
    types_hash_bucket_size 64;
    server_names_hash_bucket_size 256;
    server_names_hash_max_size 2048;
    variables_hash_bucket_size 128;

    server_tokens off;

    server {
        listen 80;

        location / {
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host "ma.dun.163.com";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Isctc-Mode "tc-ma";
            proxy_pass http://ma.dun.163.com;
        }
    }
}