Skip to content

签名算法

所有 Open Platform API 请求都需要签名鉴权,签名方式极简

sign = MD5(timestamp + body + appSecret)

鉴权信息全部放在 HTTP Header,请求体(body)保持为纯业务 JSON。

Header 三件套

Header类型说明
X-Loxily-AppKeystring项目 App Key
X-Loxily-Timestampnumber(字符串形式)Unix 秒(或毫秒),5 分钟内有效
X-Loxily-Signstring(32 字符小写 hex)MD5 签名,见下

签名公式

sign = MD5(<timestamp> + <body> + <appSecret>)
  • <timestamp>:Header X-Loxily-Timestamp 的值,直接作为字符串参与拼接
  • <body>HTTP 请求体原始字节串(UTF-8)。GET 或无 body 的请求用空字符串 ""
  • <appSecret>:项目 App Secret(与 X-Loxily-AppKey 对应)
  • 结果取 小写 16 进制(32 字符)

没有 URL 编码、没有参数排序、没有 canonical JSON、没有中间哈希——直接三段字符串拼接后求 MD5。

示例

假设:

timestamp1713780317
body(请求体原样){"name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]}
appSecretmy_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

  1. 生成签名时用的 body 必须与 HTTP 发送的完全一致的字节序列(同一份 JSON 字符串,不要在发送前再 pretty-print / 重新序列化)
  2. timestamp 使用字符串形式,不要在转换过程中丢精度
  3. UTF-8 编码一致——大多数语言的 MD5 函数默认就是 UTF-8