开放 API 调用说明文档
欢迎使用云签名授权中心开放接口。外部开发者可以通过分配的 API 凭证(ID 与 Secret)以安全签名机制直接调用本中心提供的签名引擎,免除了使用 Wails 客户端的限制。
概述与 API 鉴权说明
为保护服务器接口不被恶意篡改与抓包重放,所有调用 /api/sign/* 的开放算签接口均需在请求 Header 中携带 API 凭证和防重放动态签名。
生产环境接口请求基准地址为:https://js.newso.top/
1. 开放接口的 ID 即为您注册/创建账户时的手机号。
2. 开放接口的 Secret 密钥可在系统管理后台由管理员分配或在操作栏点击“重置密钥”生成,请妥善保管,切勿在客户端明文传输。
Header 认证三要素
| Header 键名 | 类型 | 说明与规则 |
|---|---|---|
| X-Api-Appid | string | 外部开发者的 AppID(即分配的登录手机号) |
| X-Api-Timestamp | string | 秒级 UNIX 时间戳(如 1718000000)。服务器校验该时间戳与当前系统时间差,相差超过 ±30 秒 的请求会被拦截。 |
| X-Api-Sign | string | 由开发者计算的动态签名验证值(64位小写 HEX 字符串) |
X-Api-Sign 签名计算方法
Timestamp (十进制整数字符串) 与当前请求的 URL Path (包含前导斜杠,如 /api/sign/xhs)。拼接公式:
待签串 = Timestamp + Path。例:"1718000000/api/sign/xhs"。X-Api-Sign 头部的值。待签串中的
Path 必须与您当前调用的 API 接口路径完全一致!例如:
- 如果调用小红书算签接口,Path 必须为:
/api/sign/xhs - 如果调用抖音 Post/Query 算签接口,Path 必须为:
/api/sign/dy/post - 如果调用抖音评论 A-Bogus 算签接口,Path 必须为:
/api/sign/dy/cmt
📖 签名计算详细步骤与对比示例
为了方便您和 AI 编程助手调试,以下是使用密钥 initialtestsecret1234567890abc,在时间戳为 1718000000 时计算的两个真实签名对比,供您核对计算逻辑是否正确:
用户注册
外部用户注册接口,注册成功后系统将自动为该手机号用户初始化点数余额与 32 位随机 API Secret。
请求参数 (JSON Body):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nickname | string | 是 | 用户昵称 |
| phone | string | 是 | 手机号,全网唯一,将用作 AppID |
| password | string | 是 | 登录密码 |
返回响应 (JSON):
{
"code": 1,
"msg": "注册成功",
"data": {
"phone": "13999999999"
}
}
用户登录 (排他会话)
用户登录云端。登录成功后返回的 session_id 需用于 Wails 客户端的心跳及身份验证。本系统支持异地挤下线逻辑,若未开启 force 参数且前处登录未退出,则需要提示前端确认。
请求参数 (JSON Body):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| phone | string | 是 | 手机号 |
| password | string | 是 | 密码 |
| force | boolean | 否 | 是否强制挤掉上次登录。传 true 将直接踢掉旧连接并强制登录;不传默认为 false。 |
冲突响应 (有其它设备在线且 force=false):
{
"code": 0,
"msg": "上次登录还没有退出",
"data": {
"conflict": true
}
}
成功响应 (200 OK):
{
"code": 1,
"msg": "登录成功",
"data": {
"session_id": "84bd4b1c-c9d3-4f91-a1e6-81cf42738a16",
"nickname": "测试开发者",
"phone": "13999999999",
"role": "user",
"balance": 100,
"expires_at": "2026-07-16T08:40:00+08:00"
}
}
心跳保活检测
Session 模式的客户端心跳检测。调用该接口可以保持客户端处于“在线”状态,并在前台被他人异地登录挤下线时,收到断开提示。
请求 Header 注入:
| Header 键名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-Auth-Session | string | 是 | 登录接口返回的 session_id 凭证。 |
在线响应 (200 OK):
{
"code": 1,
"msg": "成功",
"data": {
"token_balance": 99.5,
"expires_at": "2026-07-16 08:40:00"
}
}
异地踢下线响应 (401 Unauthorized):
{
"code": 0,
"msg": "您的账号已在其他地方登录,当前连接已被强制断开",
"data": {
"code": "session_replaced"
}
}
抖音 Post/Query 算签
用于计算抖音请求所需的 X-Bogus 签名值。成功计算会扣除账户 1.0 个点数(Token)。
请求参数 (JSON Body):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| params | string | 是 | 待拼接 X-Bogus 的完整 Query 请求参数串,不含 ? (例如 device_id=123&iid=456) |
| body | string | 否 | POST 请求的内容,如无传空或不传 |
| user_agent | string | 是 | 发起请求的浏览器 User-Agent 字符串。签算引擎需要对 UA 进行混淆提取 |
返回响应 (200 OK):
{
"code": 1,
"msg": "成功",
"data": {
"x_bogus": "DFSzSwVLdUtANW/MSBfQ8L9WXBJz"
}
}
抖音评论 A-Bogus 算签
用于计算抖音评论、搜索等接口所需的 A-Bogus 签名。成功计算扣除 1.0 个点数(Token)。
请求参数 (JSON Body):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 是 | 抖音评论接口的完整请求 URL |
| user_agent | string | 是 | 发起请求的浏览器 User-Agent 字符串 |
返回响应 (200 OK):
{
"code": 1,
"msg": "成功",
"data": {
"a_bogus": "DFSzSwVLdUtANW/MSBfQ8L9WXBJz..."
}
}
小红书全套头部算签
全套生成小红书防爬虫所需的 x-s, x-s-common, x-t, x-xray-traceid 等自定义头。成功扣除 1.0 个点数(Token)。
请求参数 (JSON Body):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| method | string | 是 | 请求方法:"GET" 或 "POST" (必须大写) |
| uri | string | 是 | API 请求的 Path 路径与 Query 参数 (例如 /api/sns/v6/homefeed?category=homefeed_recommend) |
| cookie | string | 是 | 小红书账号的 Cookie 串。算签模块需从 Cookie 中提取 a1 校验位。 |
| payload | any | 否 | 若是 POST 请求,传传参的 JSON 原始 Body 对象;GET 请求可传 null |
返回响应 (200 OK):
{
"code": 1,
"msg": "成功",
"data": {
"x-s": "XYT_2UQhPsHCH0c1PUhMHjIj2erjwjQ...",
"x-s-common": "2UQAPsHC+aIjqArjwjHjNsQ...",
"x-t": "1718000000000",
"x-xray-traceid": "cf66f14d5fcf1298ab3dbcfa4c18b676"
}
}
Python 对接调用示例
使用 Python requests 库对待签名接口进行签算及发送算签请求的完整范例:
import time
import hmac
import hashlib
import requests
# 开发者密钥配置
APPID = "13999999999" # 你的手机号
SECRET = "your_allocated_secret_key" # 你的 32 位 Secret 密钥
def get_api_headers(path):
timestamp = str(int(time.time()))
# 拼接签名串: Timestamp + Path
message = timestamp + path
# HMAC-SHA256 签名计算
sig = hmac.new(
SECRET.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).hexdigest()
return {
"X-Api-Appid": APPID,
"X-Api-Timestamp": timestamp,
"X-Api-Sign": sig,
"Content-Type": "application/json"
}
# 示例:请求小红书签名服务
url = "https://js.newso.top/api/sign/xhs"
path = "/api/sign/xhs"
headers = get_api_headers(path)
data = {
"method": "GET",
"uri": "/api/sns/v6/homefeed?category=homefeed_recommend",
"cookie": "a1=18f8d9bxxxxxx;",
"payload": None
}
try:
resp = requests.post(url, headers=headers, json=data)
print("状态码:", resp.status_code)
print("签名头响应:", resp.json())
except Exception as e:
print("请求异常:", e)
Go 对接调用示例
Go 语言下进行 API 开放鉴权并向云签名服务发送请求的代码:
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
AppID = "13999999999"
Secret = "your_allocated_secret_key"
)
func main() {
url := "https://js.newso.top/api/sign/xhs"
path := "/api/sign/xhs"
timestamp := time.Now().Unix()
// 1. 签名串: Timestamp + Path
rawMessage := fmt.Sprintf("%d%s", timestamp, path)
mac := hmac.New(sha256.New, []byte(Secret))
mac.Write([]byte(rawMessage))
sign := hex.EncodeToString(mac.Sum(nil))
// 2. 构造请求体
reqBody, _ := json.Marshal(map[string]interface{}{
"method": "GET",
"uri": "/api/sns/v6/homefeed?category=homefeed_recommend",
"cookie": "a1=18f8d9bxxxxxx;",
"payload": nil,
})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(reqBody))
// 3. 设定 Header
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Appid", AppID)
req.Header.Set("X-Api-Timestamp", strconv.FormatInt(timestamp, 10))
req.Header.Set("X-Api-Sign", sign)
// 4. 发送请求
client := &http.Client{Timeout: 5 * time.Second}
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求出错:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println("状态码:", resp.StatusCode)
fmt.Println("返回数据:", string(body))
}