主题
1. 签名参数说明
衡石在计算 hmac 签名时,支持多个参数。多个参数签名的加密字段顺序如下:
appShareHash -> having -> where -> appParam -> utcSecond -> userAttr
签名文本格式:
app={appShareHash}&having=$having&where=${where}&appParam=${appParam}&utcSecond=${utcSecond}&userAttr=${userAttr}
appParam 参数中,只有 sig=true 的参数才能参与到计算 hmac 签名里面.
2. 计算签名nodejs代码示例
javascript
const having = null;
// 过滤器控件
const where = [
{
"datasetId": 3,
"fieldName": "性别",
"use": "checkbox",
"kind": "function",
"op": "=",
"args": [
{ "kind": "field", "op": "性别", "dataset": 2 },
{ "kind": "constant", "op": "男" }
]
},
{
"appId": 100,
"datasetId": 2,
"kind": "formula",
"op": "{性别}='男'"
}
];
// 参数
const appParam = [
{ "name": "省份名称", "value": "湖北" },
// sig = true 才参与签名
{ "name": "城市名称", "value": "武汉", "sig":true },
{ "name": "省份名称", "value": "湖北", "appId": 100 },
{ "name": "城市名称", "value": "武汉", "appId": 100, "sig":true }
];
// 当 开启hmac有效期时才需要
const utcSecond = null; // new Date().getTime()
const hmacKey = 'hmac签名密钥'
const appShareHash = 'app的share hash'
// 参与计算签名的文本,需要按参数顺序拼接
// 1. 首先 appShareHash 必须参与签名
let encryptText = `app=${appShareHash}`
let queryString = ''
// 2. having 有值才参与签名
if(having && having.length > 0){
const str = JSON.stringify(having)
encryptText += `&having=` + str
// url的参数的值需要 encodeURIComponent
queryString += '&having=' + encodeURIComponent(str)
}
// 3. having 有值才参与签名
if(where && where.length > 0){
const str = JSON.stringify(where)
encryptText += `&where=` + str
// url的参数的值需要 encodeURIComponent
queryString += '&where=' + encodeURIComponent(str)
}
// 4. appParam
if(appParam && appParam.length > 0){
// 过滤出 sig = true的才参与签名的参数
const encryptParams = appParam.filter(item => appParam.sig)
if(encryptParams.length > 0){
encryptText += `&appParam=` + JSON.stringify(encryptParams)
}
// 注意这里url参数里面的appParam的值 依然是 带所有的参数(包括没有 sig=true的)
// url的参数的值需要 encodeURIComponent
queryString += '&appParam=' + encodeURIComponent(appParam)
}
// 5. 当 开启hmac有效期时才需要
if(utcSecond){
encryptText += '&utcSecond=' + utcSecond
queryString += '&utcSecond=' + utcSecond
}
// 6. 当开启 只允许系统内用户访问 并且 使用了用户属性 时, 给指定的用户属性 签名
if(userAttr){
// 注意: 如果用户属性是多值 或者 有非法字体, 需要 encodeURIComponent
encryptText += '&userAttr=' + userAttr
queryString += '&userAttr=' + userAttr
}
// 计算hmac签名
const signature = crypto.createHmac('sha1', hmacKey).update(encryptText).digest('hex');
queryString += '&signature=' + signature
// 最终带签名的链接
const shareURL = `/share/app/${appShareHash}` + queryString.replace('&', '?', 1)