签名算法
所有 Open Platform API 请求都需要签名鉴权,签名方式极简:
sign = MD5(timestamp + body + appSecret)鉴权信息全部放在 HTTP Header,请求体(body)保持为纯业务 JSON。
Header 三件套
| Header | 类型 | 说明 |
|---|---|---|
X-Loxily-AppKey | string | 项目 App Key |
X-Loxily-Timestamp | number(字符串形式) | Unix 秒(或毫秒),5 分钟内有效 |
X-Loxily-Sign | string(32 字符小写 hex) | MD5 签名,见下 |
签名公式
sign = MD5(<timestamp> + <body> + <appSecret>)<timestamp>:HeaderX-Loxily-Timestamp的值,直接作为字符串参与拼接<body>:HTTP 请求体原始字节串(UTF-8)。GET 或无 body 的请求用空字符串""<appSecret>:项目 App Secret(与X-Loxily-AppKey对应)- 结果取 小写 16 进制(32 字符)
没有 URL 编码、没有参数排序、没有 canonical JSON、没有中间哈希——直接三段字符串拼接后求 MD5。
示例
假设:
| timestamp | 1713780317 |
| body(请求体原样) | {"name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]} |
| appSecret | my_secret_key |
拼接后:
1713780317{"name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]}my_secret_key求 MD5(小写 hex),结果即为 X-Loxily-Sign 的值。
代码示例
Java
java
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
public class LoxilySign {
public static String sign(String timestamp, String body, String appSecret) throws Exception {
String source = timestamp + body + appSecret;
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(source.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : digest) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}Python
python
import hashlib
def sign(timestamp: str, body: str, app_secret: str) -> str:
source = f"{timestamp}{body}{app_secret}"
return hashlib.md5(source.encode("utf-8")).hexdigest()JavaScript / Node.js
javascript
const crypto = require('crypto');
function sign(timestamp, body, appSecret) {
return crypto.createHash('md5')
.update(`${timestamp}${body}${appSecret}`, 'utf8')
.digest('hex');
}Go
go
package main
import (
"crypto/md5"
"fmt"
)
func Sign(timestamp, body, appSecret string) string {
data := timestamp + body + appSecret
return fmt.Sprintf("%x", md5.Sum([]byte(data)))
}完整请求示例
bash
TIMESTAMP=$(date +%s)
BODY='{"client_task_id":"uuid-1","name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]}'
SIGN=$(printf '%s' "${TIMESTAMP}${BODY}my_secret_key" | md5)
curl -X POST "https://api.loxily.com/api/open/v1/tasks/create" \
-H "Content-Type: application/json" \
-H "X-Loxily-AppKey: 5685414646a54423c891d87194d87f3f" \
-H "X-Loxily-Timestamp: ${TIMESTAMP}" \
-H "X-Loxily-Sign: ${SIGN}" \
-d "${BODY}"对接 checklist
- 生成签名时用的
body必须与 HTTP 发送的完全一致的字节序列(同一份 JSON 字符串,不要在发送前再 pretty-print / 重新序列化) timestamp使用字符串形式,不要在转换过程中丢精度- UTF-8 编码一致——大多数语言的 MD5 函数默认就是 UTF-8