## 通信协议 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://verify.dun.163yun.com/vx/xx/check 公共参数 | 每个接口都包含的通用参数 | 详见 公共参数 (http://support.dun.163.com/documents/391676076156063744?docId=411012634773868544&locale=zh-cn#%E8%AF%B7%E6%B1%82%E5%85%AC%E5%85%B1%E5%8F%82%E6%95%B0) 说明 私有参数 | 每个接口特有的参数 | 详见每个API接口定义 # 公共参数 公共参数是用于标识产品和接口鉴权目的的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,每次请求均需要携带这些参数。 ## 请求公共参数 参数名称 | 类型 | 是否必选 | 最大长度 | 描述 secretId | String | Y | 32 | 产品秘钥 id ,在网易易盾创建产品时统一分配,产品标识 businessId | String | Y | 32 | 业务id ,在网易易盾创建产品时统一分配,业务标识 version | String | Y | 4 | 接口版本号,可选值 v1 timestamp | Number | Y | 13 | 请求当前 UNIX 时间戳(毫秒单位),请注意服务器时间是否同步 nonce | Number | Y | 11 | 随机正整数,与 timestamp 联合起来,用于防止重放攻击 signature | String | Y | 32 | 请求签名,用来验证此次请求的合法性,具体算法见 接口鉴权 (http://support.dun.163.com/documents/391676076156063744?docId=411012634773868544&locale=zh-cn#%E7%94%B3%E8%AF%B7%E5%AE%89%E5%85%A8%E5%87%AD%E8%AF%81) signatureMethod | String | N | 32 | 签名算法,可选值为MD5、SHA1、SHA256、SM3。如果不传该字段,默认采用MD5算法生成签名。 ## 响应通用字段 所有接口响应值采用 json 格式, 如无特殊说明,每次请求的返回值中,都包含下面字段: 参数名称 | 类型 | 描述 code | Number | 接口调用状态,200:正常,其他值:调用出错,返回码见 响应返回码 (http://support.dun.163.com/documents/391676076156063744?docId=411012634773868544&locale=zh-cn#%E5%93%8D%E5%BA%94%E8%BF%94%E5%9B%9E%E7%A0%81) msg | String | 结果说明,如果接口调用出错,那么返回错误描述,成功返回 ok result | String | 接口返回结果,各个接口自定义 ## 响应返回码 响应返回码(code)反应了网易易盾服务 API 调用和执行的概要结果。当返回码不为 200 时, 表示请求未正常执行,返回码描述 (msg) 对该结果进行了细化补充,用户可根据返回码判断 API 的执行情况。 所有接口调用返回值均包含 code 和 msg 字段, code 为返回码值,msg 为返回码描述信息,返回码表如下: 返回码 | 返回码描述 | 说明 200 | ok | 接口调用成功 400 | bad request | 请求缺少 secretId 或 businessId 401 | forbidden | secretId 或 businessId 错误 402 | business offline | 业务未上线 405 | param error | 请求参数异常 410 | signature failure | 签名验证失败,请重新参考demo签名代码 411 | high frequency | 请求频率或数量超过限制 420 | request expired | 请求过期 430 | replay attack | 重放攻击 503 | service unavailable | 接口异常 504 | exceed business call limit | 次数超限 505 | service expire | 服务未开通或已过期 508 | trailcount not enough | 试用条数不足 # 接口鉴权 网易易盾的所有服务使用签名方法对接口进行鉴权,所有接口每一次请求都需要包含签名信息(signature 参数),以验证用户身份,防止信息被恶意篡改。 ## 申请安全凭证 在第一次使用 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 。 - 选择与 secretId 配对的 secretKey ,加到上一步构造好的参数字符串之后,如 secretKey=6308afb129ea00301bd7c79621d07591 ,则最后的参数字符串为 bar2baz4foo1foobar36308afb129ea00301bd7c79621d07591。 - 把上一步骤拼装好的字符串采用 utf-8 编码,使用提供的签名算法对字符串进行摘要,计算得到 signature 参数值,将其加入到接口请求参数中即可。 签名生成示例代码: Code (java): /** * 生成签名信息 * @param secretKey 产品私钥 * @param params 接口请求参数名和参数值map,不包括signature参数名 * @return * @throws UnsupportedEncodingException */ public static String getSignature(String secretKey, Map params) throws UnsupportedEncodingException { return getSignature(secretKey, params, params.get("signatureMethod")); } /** * 生成签名信息 * @param secretKey 产品私钥 * @param params 接口请求参数名和参数值map,不包括signature参数名 * @param signatureMethod 加密方法 * @return * @throws UnsupportedEncodingException */ public static String genSignature(String secretKey, Map params, String signatureMethod) throws UnsupportedEncodingException { // 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); if (StringUtils.isEmpty(signatureMethod)) { // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。 return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8")); } else { switch (SignatureMethodEnum.valueOf(StringUtils.upperCase(signatureMethod))) { case MD5: return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8")); case SHA1: return DigestUtils.sha1Hex(paramBuffer.toString().getBytes("UTF-8")); case SHA256: return DigestUtils.sha256Hex(paramBuffer.toString().getBytes("UTF-8")); case SM3: return sm3DigestHex(paramBuffer.toString().getBytes("UTF-8")); default: return ""; } } return ""; } Code (python): #!/usr/bin/env python # -*- coding: utf-8 -*- """生成签名信息 Args: secretKey 产品私钥 params 接口请求参数,不包括signature参数 """ def gen_signature(secretKey, params=None): params_str = "" for k in sorted(params.keys()): params_str += str(k)+ str(params[k]) params_str += secretKey return hashlib.md5(params_str).hexdigest() Code (PHP): /** * 生成签名信息 * $secretKey 产品私钥 * $params 接口请求参数,不包括signature参数 */ function gen_signature($secretKey,$params){ ksort($params); $buff=""; foreach($params as $key=>$value){ if($value !== null) { $buff .=$key; $buff .=$value; } } $buff .= $secretKey; return md5(mb_convert_encoding($buff, "utf8", "auto")); } Code (csharp): // 根据secretKey和parameters生成签名 public static String genSignature(String secretKey, Dictionary parameters) { parameters = parameters.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value); StringBuilder builder = new StringBuilder(); foreach (KeyValuePair kv in parameters) { builder.Append(kv.Key).Append(kv.Value); } builder.Append(secretKey); String tmp = builder.ToString(); MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(Encoding.UTF8.GetBytes(tmp)); builder.Clear(); foreach (byte b in result) { builder.Append(b.ToString("x2").ToLower()); } return builder.ToString(); } Code (js): var genSignature=function(secretKey,paramsJson){ var sorter=function(paramsJson){ var sortedJson={}; var sortedKeys=Object.keys(paramsJson).sort(); for(var i=0;i