规范说明
通信协议
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接口地址 | 详见 短信发送接口 |
公共参数 | 每个接口都包含的通用参数 | 详见 公共参数 说明 |
私有参数 | 每个接口特有的参数 | 详见每个API接口定义 |
公共参数
公共参数是用于标识产品和接口鉴权目的的参数,如非必要,在每个接口单独的接口文档中不再对这些参数进行说明,每次请求均需要携带这些参数。
请求公共参数
参数名称 | 类型 | 是否必选 | 最大长度 | 描述 |
---|---|---|---|---|
secretId | String | Y | 32 | 产品秘钥 id ,在网易易盾创建产品时统一分配,产品标识 |
businessId | String | Y | 32 | 业务id ,在网易易盾创建产品时统一分配,业务标识 |
version | String | Y | 4 | 接口版本号,可选值 v2 |
timestamp | Number | Y | 13 | 请求当前 UNIX 时间戳,请注意服务器时间是否同步 |
nonce | String | Y | 32 | 随机字符串,与 timestamp 联合起来,用于防止重放攻击 |
signature | String | Y | 32 | 请求签名,用来验证此次请求的合法性,具体算法见 接口鉴权 |
响应通用字段
所有接口响应值采用 json 格式, 如无特殊说明,每次请求的返回值中,都包含下面字段:
参数名称 | 类型 | 描述 |
---|---|---|
code | Number | 接口调用状态,200:正常,其他值:调用出错,返回码见 响应返回码 |
msg | String | 结果说明,如果接口调用出错,那么返回错误描述,成功返回 ok |
data | String | 接口返回结果,各个接口自定义 |
响应返回码
响应返回码(code)网易易盾服务 API 调用和执行的概要结果。当返回码不为 200 时, 表示请求未正常执行,返回码描述 (msg) 对该结果进行了细化补充,用户可根据返回码判断 API 的执行情况。
所有接口调用返回值均包含 code 和 msg 字段, code 为返回码值,msg 为返回码描述信息,返回码表如下:
返回码 | 返回码描述 | 说明 |
---|---|---|
200 | ok | 接口调用成功 |
400 | bad request | 请求缺少 secretId 或 businessId |
401 | forbidden | secretId 或 businessId 错误 |
405 | param error | 请求参数异常 |
410 | signature failure | 签名验证失败,请重新参考demo签名代码 |
420 | request expired | 请求过期 |
421 | contentTypeError | 请求参数错误 |
429 | too many requests | 次数超限 |
430 | replay attack | 重放攻击 |
440 | decode error | 解密错误 |
450 | wrong token | token错误 |
503 | service unavailable | 接口异常 |
506 | exceed phone send limit | 单手机号发送频率限制 |
507 | balance not enough | 套餐余量不足 |
508 | money is not enough | 试用条数不足 |
接口鉴权
网易易盾的所有服务使用签名方法对接口进行鉴权,所有接口每一次请求都需要包含签名信息(signature 参数),以验证用户身份,防止信息被恶意篡改。
申请安全凭证
在第一次使用 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 。
- 选择与 secretId 配对的 secretKey ,加到上一步构造好的参数字符串之后,如 secretKey=6308afb129ea00301bd7c79621d07591 ,则最后的参数字符串为 bar2baz4foo1foobar36308afb129ea00301bd7c79621d07591。
- 把c步骤拼装好的字符串采用 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){
// 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. 将secretKey拼接到最后
sb.append(secretKey);
// 4. MD5是128位长度的摘要算法,转换为十六进制之后长度为32字符
return DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
}
#!/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()
/**
* 生成签名信息
* $secretKey 产品私钥
* $params 接口请求参数,不包括signature参数
*/
function gen_signature($secretKey,$params){
ksort($params);
$buff="";
foreach($params as $key=>$value){
$buff .=$key;
$buff .=$value;
}
$buff .= $secretKey;
return md5(mb_convert_encoding($buff, "utf8", "auto"));
}
// 根据secretKey和parameters生成签名
public static String genSignature(String secretKey, Dictionary<String, String> parameters)
{
parameters = parameters.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<String, String> 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();
}
var genSignature=function(secretKey,paramsJson){
var sorter=function(paramsJson){
var sortedJson={};
var sortedKeys=Object.keys(paramsJson).sort();
for(var i=0;i<sortedKeys.length;i++){
sortedJson[sortedKeys[i]] = paramsJson[sortedKeys[i]]
}
return sortedJson;
}
var sortedParam=sorter(paramsJson);
var needSignatureStr="";
for(var key in sortedParam){
var value=sortedParam[key];
needSignatureStr=needSignatureStr+key+value;
}
needSignatureStr+=secretKey;
var md5er = crypto.createHash('md5');//MD5加密工具
md5er.update(needSignatureStr,"UTF-8");
return md5er.digest('hex');
};
短信发送接口
接口地址
https://sms.dun.163yun.com/v2/sendsms
接口描述
该接口主要功能
- 发送短信到用户
请求参数
公共参数已省略,详细见 公共参数,其他参数如下:
参数名称 | 类 型 | 是否必选 | 最大长度 | 描述 |
---|---|---|---|---|
mobile | String | Y | 11 | 手机号;若发送国际短信,请去掉手机号前的0 |
params | String | Y | 500 | {"code":"123","time":"20180816"} |
templateId | String | Y | 20 | 模板id |
paramType | String | Y | 该字段必填:“json” | |
internationalCode | String | N | 国内短信业务不需要此参数。调用国际短信时,在此传国家代码。国家代码大全 |
响应结果
响应字段如下,响应通用字段已省略,详细见响应通用字段:
data 数据结构
参数名称 | 类型 | 描述 |
---|---|---|
result | Number | 接口调用状态,200:正常,其他值:调用出错,返回码见 响应结果码 |
requestId | String | 本次请求的唯一标识符,通过该符号查询短信发送状态接口可以查询短信发送状态 |
响应结果码
响应返回码(result)。当返回码不为 200 时, 表示请求未正常执行。
所有接口调用返回值均包含 result 字段, 返回码表如下:
返回码 | 结果码描述 | 说明 |
---|---|---|
200 | ok | 接口调用成功 |
203 | service exception | 服务异常 |
206 | mobile error | 手机号码不正确 |
216 | content error | 短信内容包含非法关键字 |
222 | over maximum limits | 超过日最大条数的限制 |
请求示例
/** 产品密钥ID,产品标识 */
private final static String SECRETID = "your_secret_id";
/** 产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露 */
private final static String SECRETKEY = "your_secret_key";
/** 业务ID,易盾根据产品业务特点分配 */
private final static String BUSINESSID = "your_business_id";
/** 本机认证服务身份证实人认证在线检测接口地址 */
private final static String API_URL = "https://sms.dun.163yun.com/v2/sendsms";
/** 实例化HttpClient,发送http请求使用,可根据需要自行调参 */
private static HttpClient httpClient = HttpClient4Utils.createHttpClient(100, 100, 2000, 2000, 2000);
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Map<String, String> params = new HashMap<String, String>();
// 1.设置公共参数
params.put("secretId", SECRETID);
params.put("businessId", BUSINESSID);
params.put("version", "v2");
params.put("timestamp", String.valueOf(System.currentTimeMillis()));
//32随机字符串
//params.put("nonce", getRandomStr(32));
params.put("nonce", "dh2u81hdah129zjk2hlla118snebd2q1");
// 2.设置私有参数d
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "123");
jsonObject.put("time", "20180816");
params.put("mobile", "18883110011");
//使用JSON格式填充模板
params.put("paramType", "json");
params.put("params", jsonObject.toJSONString());
params.put("templateId", "10000");
//需要上行的时候,这里需要设置为true
params.put("needUp", "true");
// 3.生成签名信息
String signature = SignatureUtils.genSignature(SECRETKEY, params);
params.put("signature", signature);
// 4.发送HTTP请求,这里使用的是HttpClient工具包,产品可自行选择自己熟悉的工具包发送请求
String response = HttpClient4Utils.sendPost(httpClient, API_URL, params);
//5.解析报文返回
ApiResponse apiResponse = gson.fromJson(response, ApiResponse.class);
//6.返回结果
String requestId = apiResponse.getData().getRequestId();
}
响应示例
当请求成功时,输出示例如下:
{
"code": 200,
"msg": "ok",
"data":
{
"result" : 200,
"requestId" : "7bgsdg2sdhfwi34hkhui"
}
}