授权验证 API
所有接口均为 POST 请求,请求和响应均使用 JSON 格式。
基础地址:
http://auth.suqd.cn
工作流程
软件客户端启动时按以下流程与授权服务器交互:
1. 软件首次启动 → 调用 /api/license/activate 激活(绑定设备) 2. 每次启动时 → 调用 /api/license/verify 验证授权是否有效 3. 运行期间 → 每 30 分钟调用 /api/license/heartbeat 保活 4. 用户换机 → 调用 /api/license/release 解绑旧设备
POST
/api/license/activate
激活设备
软件首次启动时调用,将授权码与该设备绑定。同一授权码可激活多台设备(数量由授权码的 max_activations 决定)。
| 参数 | 类型 | 说明 |
|---|---|---|
| license_key* | string | 授权码,格式 QD-XXXX-XXXX-XXXX-XXXX |
| machine_id* | string | 设备唯一指纹(推荐 CPU + 硬盘序列号 MD5) |
| machine_name可选 | string | 设备名称,便于后台识别 |
| os可选 | string | 操作系统,如 Windows 11 |
| version可选 | string | 软件版本号 |
cURL
PHP
Python
JavaScript
Java
curl -X POST "http://auth.suqd.cn/api/license/activate" \
-H "Content-Type: application/json" \
-d '{
"license_key": "QD-ABCD-1234-EFGH-5678",
"machine_id": "a1b2c3d4e5f6",
"machine_name": "办公室电脑",
"os": "Windows 11"
}'
$ch = curl_init('http://auth.suqd.cn/api/license/activate');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'license_key' => 'QD-ABCD-1234-EFGH-5678',
'machine_id' => 'a1b2c3d4e5f6',
'machine_name' => '办公室电脑',
'os' => 'Windows 11',
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($resp['code'] === 200 && $resp['data']['success']) {
echo '激活成功';
} else {
echo '激活失败:' . $resp['message'];
}
import requests
resp = requests.post(
'http://auth.suqd.cn/api/license/activate',
json={
'license_key': 'QD-ABCD-1234-EFGH-5678',
'machine_id': 'a1b2c3d4e5f6',
'machine_name': '办公室电脑',
'os': 'Windows 11'
},
timeout=10
).json()
if resp['code'] == 200 and resp['data']['success']:
print('激活成功')
else:
print('激活失败:', resp['message'])
const res = await fetch('http://auth.suqd.cn/api/license/activate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
license_key: 'QD-ABCD-1234-EFGH-5678',
machine_id: 'a1b2c3d4e5f6',
machine_name: '办公室电脑',
os: 'Windows 11'
})
});
const data = await res.json();
if (data.code === 200 && data.data.success) {
console.log('激活成功');
} else {
console.error('激活失败:', data.message);
}
HttpClient client = HttpClient.newHttpClient();
String body = """
{
"license_key": "QD-ABCD-1234-EFGH-5678",
"machine_id": "a1b2c3d4e5f6",
"machine_name": "办公室电脑"
}
""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("http://auth.suqd.cn/api/license/activate"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
响应示例:
{
"code": 200,
"message": "激活成功",
"data": {
"success": true,
"message": "activated"
}
}
POST
/api/license/verify
验证授权
软件每次启动时调用,验证授权码和设备是否合法。返回授权码的产品、套餐、功能开关、到期时间等信息。
| 参数 | 类型 | 说明 |
|---|---|---|
| license_key* | string | 授权码 |
| machine_id可选 | string | 不传则只校验授权码有效性 |
成功响应:
{
"code": 200,
"message": "验证通过",
"data": {
"valid": true,
"license": {
"key": "QD-ABCD-1234-EFGH-5678",
"product": "EDU_MALL",
"plan": "PRO",
"features": {
"dashboard": true,
"mail": true,
"ai": false
},
"max_activations": 5,
"activated_count": 1,
"expire_time": "2027-12-31 23:59:59"
}
}
}
失败响应(HTTP 403):
{
"code": 403,
"message": "LICENSE_EXPIRED",
"data": null
}
可能返回的错误码:
·
·
·
·
·
LICENSE_NOT_FOUND - 授权码不存在·
LICENSE_EXPIRED - 已过期·
LICENSE_REVOKED - 已被吊销·
MAX_ACTIVATIONS_REACHED - 设备数已达上限
POST
/api/license/heartbeat
心跳保活
软件运行期间每 30 分钟调用一次,向服务器报告设备在线状态。用于实时统计活跃设备和在线时长。
| 参数 | 类型 | 说明 |
|---|---|---|
| license_key* | string | 授权码 |
| machine_id* | string | 设备指纹 |
响应示例:
{
"code": 200,
"message": "ok",
"data": {
"timestamp": 1726900000
}
}
POST
/api/license/release
释放设备
软件卸载或用户换机时调用,解绑此设备,释放一个激活名额。
| 参数 | 类型 | 说明 |
|---|---|---|
| license_key* | string | 授权码 |
| machine_id* | string | 设备指纹 |
客户端集成建议
1. 生成稳定的设备指纹
// PHP 示例
$machineId = md5(
php_uname('n') . '|' . // 主机名
$_SERVER['PROCESSOR_IDENTIFIER'] ?? '' . '|' . // CPU
disk_free_space('C:') // 硬盘剩余空间(较稳定)
);
2. 本地缓存验证结果
为避免每次启动都请求服务器,可以本地缓存授权状态,比如 24 小时内不再请求。缓存字段建议包含:授权码、到期时间、验证时间、签名。
3. 离线宽限期
如果无法连接服务器(如内网环境),可以允许软件离线运行 N 天(比如 7 天),超过后必须联网验证。这样兼顾用户体验和授权安全。
4. 校验响应签名(可选)
服务端返回结果后,可以在响应里加签名,客户端校验签名防止中间人篡改。需要与客服联系开启此功能。
安全提示:客户端不要硬编码敏感信息(如 API 密钥),也不要在本地做核心授权判断——所有关键校验必须在服务端完成。