服务端接口文档
API 说明
API 服务域名
https://ums-api.qiniu.com/
请求鉴权
API 服务采用Qiniu Auth 的方式进行鉴权。
每一个请求均需在 HTTP 请求头部增加一个 Authorization 字段,其值为符合管理凭证的字符串,形式如下:
Authorization: <QiniuToken>
生成管理凭证
可以参考如下代码生成管理凭证。
// golang
// 构造待签名的 Data
// 1. 添加 Path
data = "<Method> <Path>"
// 2. 添加 Query,前提: Query 存在且不为空
if "<RawQuery>" != "" {
data += "?<RawQuery>"
}
// 3. 添加 Host
data += "\nHost: <Host>"
// 4. 添加 Content-Type,前提: Content-Type 存在且不为空
if "<Content-Type>" != "" {
data += "\nContent-Type: <Content-Type>"
}
// 5. 添加回车
data += "\n\n"
// 6. 添加 Body,前提: Content-Length 存在且 Body 不为空,同时 Content-Type 存在且不为空或 "application/octet-stream"
bodyOK := "<Content-Length>" != "" && "<Body>" != ""
contentTypeOK := "<Content-Type>" != "" && "<Content-Type>" != "application/octet-stream"
if bodyOK && contentTypeOK {
data += "<Body>"
}
// 计算 HMAC-SHA1 签名,并对签名结果做 URL 安全的 Base64 编码
sign = hmac_sha1(data, "Your_Secret_Key")
encodedSign = urlsafe_base64_encode(sign)
// 将 Qiniu 标识与 AccessKey、encodedSign 拼接得到管理凭证
<QiniuToken> = "Qiniu " + "Your_Access_Key" + ":" + encodedSign
请求返回
号码认证服务的API,统一使用如下形式的返回结果。
{
"request_id": "Yl0BACAisJ3-qlkX",
"code": 200,
"message": "success",
"data": {}
}
参数 | 类型 | 说明 |
---|---|---|
request_id | string | 请求ID |
code | int | 200:请求成功;其他:请求失败。 |
message | string | 当请求失败时,返回失败描述信息。 |
data | object | 当请求成功时,返回业务数据。具体看每个接口的解析。 |
一键认证
请求方法
POST: /v1/verification/login
Content-Type: application/json
认证方式: Qiniu-Auth
请求参数
{
"out_id": "req-1",
"app_id":"h40ndbd35",
"token": "STsid0000001683366126670vx3grYley91DoSwwa0f5LxRxBWhnWacJ",
"client_ip": "1.1.1.1",
"encrypt_type": 0,
"timestamp": 1683360751,
"sign": "be9def62498a5025d44180b7a81d8236e400a52813af8ed06900b1b9d1dff2f6"
}
参数解析
参数 | 类型 | 是否必选 | 说明 |
---|---|---|---|
out_id | string | 可选 | 请求方生成的流水号。 |
app_id | string | 必选 | 号码认证服务的应用ID |
token | string | 必选 | 客户端APP,通过号码认证服务SDK,获取到的一键登录 Token。 |
client_ip | string | 可选 | 客户端IP地址,可选。 |
encrypt_type | integer | 必选 | 返回手机号码的加密方式:0,aes加密;1,rsa 加密。当使用 RSA 加密时,在申请应用时,需要配置RSA 公钥。 |
timestamp | integer | 必选 | 请求的时间戳,秒级时间戳 |
sign | string | 必选 | 请求的签名 |
sign 签算
sign 字段是对请求其余字段的签名。
签算内容生成:请求参数,除 sign 字段外,所有字段,按字段名升序排列,生成url query 形式的字符串。无值的字段,不能省略。
使用hmacSHA256 算法 ,使用应用的appKey,对待签算内容,进行签算。
代码示例:
// 所有可选字段都有的签算内容生成
data := "app_id=app_1&client_ip=1.1.1.1&encrypt_type=0&out_id=req-1×tamp=0&token=xxxxxx"
sign := hmacSHA256(data, appKey)
// client_ip 不填的签算内容生成
data =: "app_id=app_1&client_ip=&encrypt_type=0&out_id=×tamp=0&token=xxxxxx"
sign := hmacSHA256(data, appKey)
签算算法,参考后面的【签算与加密】部分。
返回结果
{
"request_id": "Yl0BACAisJ3-qlkX",
"code": 200,
"message": "success",
"data": {
"out_id": "req-1",
"msg_id": "msg-1",
"timestamp": 123456,
"mobile": "ABABCDCD"
}
}
data 部分说明
参数 | 类型 | 是否必选 | 说明 |
---|---|---|---|
out_id | string | 可选 | 请求方生成的流水号。 |
msg_id | string | 必选 | 七牛生成的消息流水号。 |
timestamp | integer | 必选 | 服务端应答时间戳。 |
mobile | string | 必选 | 手机号码密文。 |
手机号码解密
手机号码返回的是密文。根据请求的 encrypt_type 选择解密算法。
- encrypt_type 为0,使用 AES 解密。
- encrypt_type 为1,使用RSA 解密。
解密算法,参考【签算与加密】部分。
本机号码验证
请求方法
POST: /v1/verification/check
Content-Type: application/json
认证方式: Qiniu-Auth
请求参数
{
"out_id": "req-1",
"app_id":"h40ndbd35",
"token": "STsid0000001683366126670vx3grYley91DoSwwa0f5LxRxBWhnWacJ",
"mobile": "13800000000",
"timestamp": 1683360751,
"sign": "be9def62498a5025d44180b7a81d8236e400a52813af8ed06900b1b9d1dff2f6"
}
参数解析
参数 | 类型 | 是否必选 | 说明 |
---|---|---|---|
out_id | string | 可选 | 请求方生成的流水号。 |
app_id | string | 必选 | 号码认证服务的应用ID |
token | string | 必选 | 客户端APP,通过号码认证服务SDK,获取到的本机号码验证 Token。 |
mobile | string | 必选 | 手机号码 |
timestamp | integer | 必选 | 请求的时间戳,秒级时间戳 |
sign | string | 必选 | 请求的签名 |
sign 签算
sign 字段是对请求其余字段的签名。
签算内容生成:请求参数,除 sign 字段外,所有字段,按字段名升序排列,生成url query 形式的字符串。无值的字段,不能省略。
使用hmacSHA256 算法 ,使用应用的appKey,对待签算内容,进行签算。
代码示例:
// 所有可选字段都有的签算内容生成
data := "app_id=app_1&mobile=13800000000&out_id=req-1×tamp=0&token=xxxxxx"
sign := hmacSHA256(data, appKey)
// out_id 不填的签算内容生成
data =: "app_id=app_1&mobile=13800000000&out_id=×tamp=0&token=xxxxxx"
sign := hmacSHA256(data, appKey)
签算算法,参考后面的【签算与加密】部分。
返回结果
{
"request_id": "AjYAAJAQ7fDXulkX",
"code": 0,
"message": "success",
"data": {
"out_id": "req-1"
"msg_id": "msg_1",
"timestamp": 0,
"is_verify": false,
"operator": 0
}
}
data 部分说明
参数 | 类型 | 是否必选 | 说明 |
---|---|---|---|
out_id | string | 可选 | 请求方生成的流水号。 |
msg_id | string | 必选 | 七牛生成的消息流水号。 |
timestamp | integer | 必选 | 服务端应答时间戳。 |
is_verify | boolean | 必选 | true 是本机号码,false,不是本机号码 |
operator | integer | 可选 | 运营商。0 未知;1 移动;2 联通;3 电信 |
签算与加密
hmacSHA256签算
请求的数据,使用应用的appKey,对请求数据进行签算。
对签算结果,进行hex 编码后,转成大写。
go代码示例
func hmacSHA256(message string, key string) string {
mac := hmac.New(sha256.New, []byte(key))
mac.Write([]byte(message))
sign := mac.Sum(nil)
return strings.ToUpper(hex.EncodeToString(sign))
}
签算测试用例
// 待签算内容(UTF-8 编码)
message := "hello world, 你好中国"
// appKey
appKey := "1234554321"
// 签算
sign := hmacSHA256(message, appKey)
assert.Equal("617098ED069332F668C47083F5983DD754DFDF94209CCBDFAE5689CD40984907", sign)
AES 解密
当加密类型使用 AES 时,使用AES CBC算法进行解密。
秘钥生成
使用 appKey,生成秘钥与初始化向量
- 对appKey 进行 md5,得到hash 值是一个长度为 16 字节的byte 数组。
- 对 hash 进行hex 编码,并转成大写。得到一个 32 字节长度的字符串。
- 字符串的前16位字符串为秘钥,后16位字符为初始化向量解密。
执行解密
使用生成的秘钥与初始化向量进行AES CBC 解密。
go代码示例
// 使用appKey,分离出 key,iv
func splitAppKey(appKey string) ([]byte, []byte) {
hash := md5.Sum([]byte(appKey))
hashString := strings.ToUpper(hex.EncodeToString(hash[:]))
return []byte(hashString[:16]), []byte(hashString[16:])
}
// 使用appKey,进行AES 解密
func Decrypt(data string, appKey string) (string, error) {
// 1,对待解密内容,进行 hex 解码,得到原始密文。
source, err := hex.DecodeString(data)
if err != nil {
return "", err
}
// 2,使用appKey,分离出 key,iv
key, iv := splitAppKey(appKey)
// 3,使用 key,iv 进行解密
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
ecb := cipher.NewCBCDecrypter(block, iv)
decrypted := make([]byte, len(source))
ecb.CryptBlocks(decrypted, source)
// 4,去掉填充数据
result := UnPadding(decrypted)
return string(result), nil
}
// 删除解密后数据的填充部分
func UnPadding(data []byte) []byte {
padding := data[len(data)-1]
return data[:(len(data) - int(padding))]
}
解密测试用例
这里提供解密测试用例,供对比测试。
密文:2253F7EA8DFB2D36439F6739CDBD7364
appKey:1234554321
解密后内容:13812341234
错误码
Code | 说明 |
---|---|
200 | 成功 |
400 | 参数错误 |
401 | 鉴权错误 |
500 | 服务器内部错误 |
30001 | APP 状态不可用 |
30002 | 请求的加密算法是 RSA,但是应用未配置RSA 公钥 |
30003 | 请求运营商服务发生异常。 |
30004 | 运营商返回错误。 |
文档反馈
(如有产品使用问题,请 提交工单)