# 账号说明
字段 | 释义 | 描述 |
---|---|---|
merchantId | 商户id | 商户 id 是您的小程序在数据接入的唯一标识,不区分环境 |
appId | appId | 与微信 appId 不同,这是您的品牌在腾讯数据接入的 appId ,也是前端 SDK 的token,区分环境 |
appSecret | appSecret | 这是您的品牌在腾讯数据接入的 appsecret ,区分环境;后端 API 需要使用 appId + appSercet 生成 signature ,具体方式见下文 |
测试环境
后端 API 测试环境 url:https://test.zhls.qq.com/
前端 SDK 测试环境 url:https://zhls.qq.com/
前端SDK url 不区分环境,均为 https://zhls.qq.com/
生产环境
后端 API 生产环境 url:https://zhls.qq.com/
前端 SDK 生产环境 url:https://zhls.qq.com/
# 签名生成方式
# 前端 SDK 上报
使用腾讯数据接入 appId 即可,区分测试和生产环境。
腾讯数据接入 appId 与微信小程序 appId 不同。腾讯数据接入 appId 通常以 bi 开头,微信小程序 appId 通常以 wx 开头。
# 接口上报
以下是签名过程会涉及的参数。
参数 | 说明 |
---|---|
app_id | 腾讯数据接入分配的应用ID |
app_secret | 腾讯数据接入分配的签名密钥,需要绝对保密 |
timestamp | 当前时间戳,单位为秒 |
nonce | 随机字符串标识,不超过32个字符 |
sign | 签名算法,目前只支持 sha256 |
signature | 最终的签名参数 |
# 计算签名
- 随机生成
timestamp
、nonce
- 拼接字符串:
app_id=&nonce=&sign=×tamp=
(key已经按字符串顺序顺次排列,不需要对value进行url encode) - 使用
sign
算法和app_secret
对拼接的字符串进行加密,然后使用hex进行编码,获得签名signature
# 示例
随机生成:
timestamp = "1542951251"
,nonce = "407313d23c3f7"
拼接字符串:
conStr = "app_id=abc&nonce=407313d23c3f7&sign=sha256×tamp=1542951251"
使用秘钥加密生成签名
app_secret="123",
signature = hex(sha256(conStr)) = "25d5806d0aadc93129879874227c348c33f8e29d70cdcb3094c6909fadb3007b"
# 请求
POST https://zhls.qq.com/api/v1/safe-report?app_id=<app_id>&nonce=<nonce>×tamp=<timestamp>&sign=<sign>&signature=<signature>
body <数据内容: JSON Object or JSON Array>
# 请求示例
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Random;
public class ZhlsApiSignature {
String app_id = "abc";
String app_secret = "xyz";
StringBuilder hexStringBuilder = new StringBuilder();
private ZhlsApiSignature() {}
/**
* Init with your key pair.
* @param app_id
* @param app_secret
*/
public ZhlsApiSignature(String app_id, String app_secret) {
this.app_id = app_id;
this.app_secret = app_secret;
}
/**
* app_id=${app_id}&nonce=${nonce}&sign=sha256×tamp=${timestamp}&signature=${signature}
* @return
* @throws Exception
*/
public String sign() throws Exception {
Random random = new Random(System.currentTimeMillis());
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonce = String.valueOf(Math.abs(random.nextLong()));
// try the doc example
// timestamp="1542951251";
// nonce="407313d23c3f7";
// ----
String str = String.format("app_id=%s&nonce=%s&sign=sha256×tamp=%s", app_id, nonce, timestamp);
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(app_secret.getBytes("UTF-8"), mac.getAlgorithm());
mac.init(secretKey);
byte[] bytes = mac.doFinal(str.getBytes("UTF-8"));
hexStringBuilder.setLength(0);
for (int i = 0; i < bytes.length; ++i) {
String hex = Integer.toHexString(0xff & bytes[i]);
if (hex.length() == 1) {
hexStringBuilder.append('0');
}
hexStringBuilder.append(hex);
}
String signature = hexStringBuilder.toString();
return str + "&signature=" + signature;
}
// public static void main(String[] args) throws Exception {
// System.out.println(new ZhlsApiSignature().sign());
// }
}
<?php
$app_id = "xyz";
$app_secret = "abc";
$date = strtotime(date('YmdHis'));
$nonce = rand(1000000, 100000000);
$str = "app_id=" . $app_id . "&nonce=" . $nonce . "&sign=sha256×tamp=" . $date;
$sign = hash_hmac('sha256', $str, $app_secret, false);
echo $sign;
?>
import hmac
import base64
from hashlib import sha256
import random,time
# python3
# refer doc here: https://mp.zhls.qq.com/youshu-docs/develop/dev_account/dev_account_access.html
#参数赋值方法
app_id='abc'
appsecret='123'
nonce=random.randint(0,90000000)
sign="sha256"
timestamp=(int)(time.time())
# 页面demo的参数计算值过程
conStr = "app_id=abc&nonce=407313d23c3f7&sign=sha256×tamp=1542951251"
private_key = "123".encode('utf-8') # 秘钥
data = conStr.encode('utf-8') # 加密数据
signature = hmac.new(private_key, data, digestmod=sha256).hexdigest()
print (signature )
# 25d5806d0aadc93129879874227c348c33f8e29d70cdcb3094c6909fadb3007b
const crypto = require('crypto');
const qs = require('qs');
module.exports = {
sign(appID, appSecret, sign, timestamp, nonce) {
const conStr = qs.stringify({
app_id: appID,
timestamp,
nonce,
sign,
}, {
sort: (a, b) => a.localeCompare(b),
encode: false,
});
// console.log(conStr)
const hmac = crypto.createHmac('sha256', appSecret);
const signature = hmac.update(Buffer.from(conStr, 'utf8')).digest('hex').toLowerCase();
// console.log(appID, appSecret, sign, timestamp, nonce, signature)
return signature;
},
};
如接口使用除 JAVA
, PHP
,PYTHON
外的开发语言,想获得签名代码样例时,请联系 youshu_helper,我们将尽快为您解决问题。
# 常见FAQ
接口调用时的签名机制,是否需要把请求 body 内容加入到签名串中?
答:不需要,只需文档中的 6 个参数。