| Version | Update Date | Change Description | Author |
|---|---|---|---|
| v1.0.1 | 2026-03-25 | Adjusted some field descriptions | Yan Yonglong |
| V1.0.0 | 2025-09-09 | Created documentation | Chen Lubin |
1.3 Token customization example:
-H "token: xxxxxxxx": token is an authentication parameter of the developer's own server. The default key is token, but it can be customized to another name in the JavaScript configuration. For example:
With init({"token_keyname":"authority"}), JavaScript sends a request similar to the following by default:
curl -X POST http://localhost:13001/api/v2/token \
-H "Content-Type: application/json" \
-H "openid: tengda" \
-H "authority: xxxxxxxx" \
-d '{
"DID": "device123",
"IMEI": "imei456",
"data": "test_data"
}'
1. secretKey is highly sensitive. Do not place it in frontend HTML, mini programs, or apps.
2. How to use the API code. You may skip this section and continue to the next one.
2.1.3 Parameter Description
| Parameters | Required | Value | Description |
|---|---|---|---|
| DID | Yes | Unique ID printed on the device; | Device ID is required |
| IMEI | No | Device IMEI | Pass an empty string when not applicable |
| openid | Yes | Pass the appid or openid mentioned above | appid and openid are the same; only the names differ |
| timestamp | Yes | Current timestamp (seconds) | Timestamp (seconds) when the server received the device alarm. Because the device time may be inaccurate, this is not the device time. |
| nonce | Yes | Random string, 8-12 characters | Nonce |
| data | No | Each business scenario has its own data generation rules | Pass an empty string when not applicable |
| secretKey | Yes | Pass the secret mentioned above, the secret key | Encryption key |
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strconv"
)
func GenerateSignature(DID, IMEI, openid string, timestamp int64, nonce, data, secretKey string) string {
// 拼接参数字符串
concatenated := DID + IMEI + openid + strconv.FormatInt(timestamp, 10) + nonce + data + secretKey
// 计算MD5哈希
hash := md5.Sum([]byte(concatenated))
// 返回32位小写hex字符串
return hex.EncodeToString(hash[:])
}
/**
* 生成MD5签名token
* @param DID 设备唯一标识
* @param IMEI 设备IMEI号,可不传,
* @param openid 开放平台ID,示例"tengda"
* @param timestamp 时间戳(秒)
* @param nonce 随机字符串
* @param data 业务数据,可以不传
* @param secretKey 签名密钥
* @return MD5签名结果(32位小写hex字符串),出错时返回null
*/
public static String getTokenV2(String DID, String IMEI, String openid,
long timestamp, String nonce,
String data, String secretKey) {
try {
// 拼接字符串
String concatenated = DID + IMEI + openid + timestamp + nonce + data + secretKey;
// 获取MD5实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算哈希值
byte[] hashBytes = md.digest(concatenated.getBytes());
// 转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
1. In the example code, read SECRET_KEY from the configuration file.
2. In the example code, sign, nonce, and timestamp are also generated by the server. Developers are not required to follow this implementation.
3. This example code is for reference only. Actual behavior may vary depending on the operating system and dependencies used by each language.
| Field | Location | Required | Value Type | Value Source | Description |
|---|---|---|---|---|---|
| openid | Request Headers | Yes | string | App open id provided by the administrator | |
| token | Request Headers | Yes | string | The session key used by the frontend application is an authentication parameter for the developer's own server. The default key is token, but it can be customized to another name in the JavaScript configuration. | The customized example is shown below the table. |
| did | body | Yes | string | Device number on the machine | |
| IMEI | body | No | string | Device IMEI; usually omitted | |
| data | body | No | string | Business data. Pass a value according to the actual business scenario. |
| Field | Value Type | Value Description | Description |
|---|---|---|---|
| error_code | int | A return value of 0 indicates success; other values indicate an error | |
| error_message | string | This field may contain a value when an error occurs, but a value is not guaranteed. | |
| error_tips | string | This is generally a message that can be shown in a frontend dialog, but a value is not guaranteed. | |
| data | string | ||
| data.sign | string | Returned signature | |
| data.nonce | string | Returned random string | |
| data.timestamp | int | Returned timestamp (seconds) |
curl -X POST http://localhost:13001/api/v2/token \
-H "Content-Type: application/json" \
-H "openid: myopenid" \
-H "token: xxxxxxxx" \
-d '{
"DID": "device123",
"IMEI": "imei456",
"data": "test_data"
}'
npm install express cors
const express = require('express');
const crypto = require('crypto');
const app = express();
const PORT = 13001;
const SECRET_KEY = 'your_server_secret_key';
function generateConcatenatedString(DID, IMEI = '', openid, timestamp, nonce, data = '', secretKey) {
return `${DID}${IMEI}${openid}${timestamp}${nonce}${data}${secretKey}`;
}
app.use(express.json());
app.post('/api/v2/token', (req, res) => {
try {
const openid = req.headers['openid'];
const { DID, IMEI = '', data = '' } = req.body;
if (!openid || !DID) {
return res.status(200).json({
error_code: 400,
error_message: "Missing required parameters",
data: {}
});
}
const nonce = crypto.randomBytes(16).toString('hex');
const timestamp = Math.floor(Date.now() / 1000);
const concatenated = generateConcatenatedString(DID, IMEI, openid, timestamp, nonce, data, SECRET_KEY);
const sign = crypto.createHash('md5').update(concatenated).digest('hex');
res.status(200).json({
error_code: 0,
error_message: {},
data: { sign, nonce, timestamp }
});
} catch (error) {
console.error('API Error:', error);
res.status(200).json({
error_code: 500,
error_message: "Internal server error",
data: {}
});
}
});
app.listen(PORT, () => {
console.log(`MD5 API服务运行在 http://localhost:${PORT}`);
});
Sign Generation API
Production: https://open.eye4cloud.com/{{open_id}}/open/v1/device/generalSign| Field Name | Required | Type | Description |
|---|---|---|---|
| device_id | Yes | string | Device ID |
| timestamp | Yes | int64 | Timestamp in seconds |
| nonce | Yes | string | Random string, 8-20 characters |
| openId | Yes | string | appid |
| secretKey | Yes | string | secretKey |
| imei | No | string | imei |
| data | No | string | data |
curl 'https://open.eye4cloud.com/{{open_id}}/open/v1/device/generalSign' \
-H 'Content-Type: application/json' \
--data-raw '{
"device_id": "xxxx",
"timestamp": 1758867195,
"nonce": "123456",
"openId": "xxx",
"secretKey": "xxx",
"password": "xxxxx"
}'
| Field Name | Type | Description |
|---|---|---|
| error_code | int | Status code: 0 indicates success; other values indicate an error |
| error_message | string | Error message; success indicates a normal response |
| data | object | {} |
| data.sign | string | sign |
Example:
{
"error_code": 0,
"error_message": "success",
"error_tips": "",
"data": {
"sign":"xxxx"
}
}