Skip to content

1. Signature Parameter Explanation

  1. HENGSHI supports multiple parameters when calculating the hmac signature. The encryption field order for multiple parameter signatures is as follows:

    appShareHash -> having -> where -> appParam -> utcSecond -> userAttr

  2. Signature text format:

    app={appShareHash}&having=$having&where=${where}&appParam=${appParam}&utcSecond=${utcSecond}&userAttr=${userAttr}

  3. In the appParam parameter, only parameters with sig=true can participate in the calculation of the hmac signature.

2. Example Node.js Code for Calculating Signatures

javascript
const having = null;

// Filter control
const where = [
        { 
            "datasetId": 3, 
            "fieldName": "Gender", 
            "use": "checkbox", 
            "kind": "function", 
            "op": "=", 
            "args": [
                { "kind": "field", "op": "Gender", "dataset": 2 }, 
                { "kind": "constant", "op": "Male" }
            ] 
        }, 
        { 
            "appId": 100, 
            "datasetId": 2, 
            "kind": "formula", 
            "op": "{Gender}='Male'" 
        }
    ];

// Parameters
const appParam = [
    { "name": "Province Name", "value": "Hubei" },
    // Only participate in signature if sig = true
    { "name": "City Name", "value": "Wuhan", "sig":true },    
    { "name": "Province Name", "value": "Hubei", "appId": 100 },
    { "name": "City Name", "value": "Wuhan", "appId": 100, "sig":true }
];

// Required only when HMAC expiration is enabled
const utcSecond = null; // new Date().getTime()

const hmacKey = 'HMAC signature key'
const appShareHash = 'app share hash'

// Text to participate in signature calculation, needs to be concatenated in parameter order
// 1. appShareHash must participate in the signature
let encryptText = `app=${appShareHash}`   
let queryString = ''

// 2. having participates in the signature if it has a value
if(having && having.length > 0){
    const str = JSON.stringify(having)
    encryptText += `&having=` + str
    // The value of the URL parameter needs to be encodeURIComponent
    queryString += '&having=' + encodeURIComponent(str)    
}
// 3. where participates in the signature if it has a value
if(where && where.length > 0){
    const str = JSON.stringify(where)
    encryptText += `&where=` + str
    // The value of the URL parameter needs to be encodeURIComponent
    queryString += '&where=' + encodeURIComponent(str)  
}

// 4. appParam
if(appParam && appParam.length > 0){
    // Filter out parameters that participate in the signature only if sig = true
  const encryptParams =  appParam.filter(item => appParam.sig)   
  if(encryptParams.length > 0){
    encryptText += `&appParam=` + JSON.stringify(encryptParams)
	}
  // Note that the value of appParam in the URL parameter still includes all parameters (including those without sig=true)
  // The value of the URL parameter needs to be encodeURIComponent
  queryString += '&appParam=' + encodeURIComponent(appParam)  
}

// 5. Required only when HMAC expiration is enabled
if(utcSecond){
    encryptText += '&utcSecond=' + utcSecond
    queryString += '&utcSecond=' + utcSecond
}

// 6. When only allowing access by users within the system and using user attributes, sign the specified user attributes
if(userAttr){
    // Note: If the user attribute is multi-valued or contains illegal characters, it needs to be encodeURIComponent
    encryptText += '&userAttr=' + userAttr
    queryString += '&userAttr=' + userAttr
}

// Calculate HMAC signature
const signature = crypto.createHmac('sha1', hmacKey).update(encryptText).digest('hex');
queryString += '&signature=' + signature

// Final URL with signature
const shareURL = `/share/app/${appShareHash}` + queryString.replace('&', '?', 1)

HENGSHI SENSE Platform User Manual