系统授权接入文档

把授权校验接到 IDCGo 实例上:激活、在线校验与解绑

1. 接入流程

1 拿到授权码 由管理员开通后生成,形如 IDCG-XXXX-XXXX-XXXX-XXXX
2 首次激活 部署完成后调用 /activate,把授权码绑定到当前域名
3 定期校验 每 1 分钟调用一次 /verify,确认授权仍有效
4 失败宽限 网络异常时先按 72 小时离线宽限运行,避免误停机
接口地址
https://api.idcxb.com/api/v1
请求方式
POST,application/json 或表单
签名盐值
已配置
在线校验间隔
1 分钟
离线宽限时间
72 小时
限流
每个 IP 每分钟 120 次
签名盐值用于校验服务端返回体是否被篡改。若显示「未修改」,请在 .env 中设置 LICENSE_SIGN_SALT 为一段随机字符串。

PHP 单文件 SDK

下载 idcgo-license.php.txt 并重命名为 idcgo-license.php, 放到你的系统授权文件中 require;licenseRequest() 已封装 JSON 提交、超时与错误归一,licenseVerifySign() 用于校验返回体签名。

把下面这段加到你的系统授权文件里,域名换成实例实际域名:
require 'idcgo-license.php';

$res = licenseRequest('/verify', [
    'license_key' => 'IDCG-XXXX-XXXX-XXXX-XXXX',
    'domain'      => 'demo.example.com',
]);

if (($res['code'] ?? -1) !== 0) {
    exit($res['message'] ?? '授权校验失败');
}

if (! licenseVerifySign($res['data'], '你的 LICENSE_SIGN_SALT')) {
    exit('返回体签名不合法');
}

通用资源(SDK / OpenAPI / 公开查询)统一列在 文档总览,本页不再重复。

2. 核心概念

授权码
产品的唯一授权凭证。大小写、空格与连字符会自动归一化,客户端不需要自己清洗。
绑定域名与 IP
授权码最多绑定 max_activations 个域名,每条绑定同时锁定服务器 IP。域名解析结果必须与 IP 一致;协议、端口、www. 会被去掉;子域名需要单独绑定,不自动继承根域名。
有效期
permanent=true 表示永久授权;否则以 expires_at 与 days_left 为准。
绑定上限
max_activations=0 表示跟随系统默认,不代表不能绑定;实际名额以成功响应里的数值为准。
在线校验
客户端定期回连 /verify。成功响应会带回后台当前的校验间隔与离线宽限,请以接口返回为准,不要写死。
离线宽限
校验失败时不要立刻停机。超过 offline_grace_hours 仍未成功校验,再判定授权失效;0 表示不设宽限。
响应签名
成功响应的 data.sign 是对其余字段的 HMAC-SHA256,用签名盐值验签即可确认未被篡改。

2.1 服务器 IP 检测

授权服务端会在激活、在线校验时自动识别请求的出口公网 IP,写入绑定记录与校验日志, 并在成功响应里返回 server_ip。客户端不需要读取网卡,也不需要手动上报 IP。

检测时机
调用 /activate、/verify、/deactivate 时自动检测,并用于比对绑定 IP。
记录位置
绑定记录的「绑定 IP」「最近来源 IP」、校验日志的「来源 IP」。
响应字段
data.server_ip 与 data.server_ip_version(IPv4 / IPv6)。
手动绑定
用户中心可点「检测」自动解析域名 IP;也可以留空,由服务端在绑定时解析。
绑定会校验域名当前解析到的 IP;如果域名解析到 CDN 或反向代理节点,检测到的就不是源站 IP,将无法通过一致性校验。请改用直接解析到授权服务器的域名。
服务器 IP 是授权校验条件之一:来源 IP 与绑定记录不一致时,/activate 与 /verify 会返回 1014 并拒绝。更换 IP 请在用户中心重新绑定,详见下方「IP 一致性校验」。

公开查询页 /check 也支持直接输入域名或服务器 IP, 返回该 IP 最近一次校验对应的授权,便于客服或用户自助核对。后台侧检测见 用户中心 API · 服务器 IP 检测。

域名 + IP 双重校验

绑定域名时填写的服务器 IP 会被锁定为该绑定记录的校验基准。之后每次 /activate、/verify, 服务端都会拿请求域名与本次请求的出口 IP 逐项比对,域名与 IP 必须同时匹配才放行。

未锁定 IP
绑定记录没有 IP 时视为不一致,返回 1014,请重新绑定以写入 IP 基准。
不一致时
域名或 IP 任一不一致都返回 1014,不刷新校验时间、不增加校验次数,并在绑定记录里标记「IP 不一致」。
更换 IP / 域名
在用户中心重新绑定该域名(点「检测」自动解析,或手动填写新 IP)即可更新基准;也可先解绑再绑定。
跳过比对
不支持。调用 /verify 必须同时传 license_key 与 domain。
{
  "code": 1014,
  "message": "服务器 IP 与绑定不一致(绑定 38.76.166.40,当前 112.48.82.6),请在用户中心重新绑定后再试",
  "data": null
}
绑定域名时,域名当前解析到的 IP 必须与服务器 IP 一致;出口 IP 变化(动态 IP、云主机迁移)后需重新绑定。若域名解析到 CDN 节点,需改用解析到源站的域名。

IP 检测接口

客户端可以在启动时调用 GET /v1/ip 获取自己的出口公网 IP,用于展示或排查网络问题。 该接口不校验授权,限流与其它接口一致。

curl "https://api.idcxb.com/api/v1/ip"
{
  "code": 0,
  "message": "ok",
  "data": {
    "ip": "38.76.166.40",
    "remote_ip": "38.76.166.40",
    "version": "IPv4",
    "public": true,
    "forwarded": false,
    "detected_at": "2026-10-28 22:10:00"
  }
}

同时,/activate 与 /verify 的成功响应也会带回 server_ip, 客户端可以缓存并在后台展示,方便和用户核对。

3. 接口一览

接口 方法 用途
/v1/ping GET 健康检查,确认授权服务器可达
/v1/ip GET 服务器 IP 检测,返回调用方出口公网 IP
/v1/activate POST 首次激活,把授权码绑定到当前域名
/v1/activate GET 链接直接激活,参数走 query
/v1/verify POST 在线校验,建议每 1 分钟调用一次
/v1/deactivate POST 解绑,释放域名名额(迁移服务器时用)
激活 / 校验成功时,响应里的 verify_interval_minutes 与 offline_grace_hours 就是后台当前的授权策略;客户端应以此为准, 不要写死在代码里。

4. 健康检查

GET https://api.idcxb.com/api/v1/ping

不校验任何参数,用于部署后确认授权服务器可达。

curl "https://api.idcxb.com/api/v1/ping"
{
  "code": 0,
  "message": "ok",
  "data": {
    "server_time": "2026-10-27 20:18:00",
    "server_ip": "38.76.166.40",
    "server_ip_version": "IPv4"
  }
}

5. 激活

POST https://api.idcxb.com/api/v1/activate

把授权码绑定到当前部署的域名,服务端会校验该域名当前解析到的 IP 与请求出口 IP 是否一致,并一并锁定。首次部署时调用一次,成功后把结果缓存到本地。

参数必填说明
license_key是授权码
domain是当前部署域名,须为真实域名
machine_code否机器码,便于排查多机使用
curl -X POST "https://api.idcxb.com/api/v1/activate" \
  -d "license_key=IDCG-ABCD-EFGH-JKLM-NPQR" \
  -d "domain=demo.example.com"
{
  "code": 0,
  "message": "激活成功",
  "data": {
    "license_key": "IDCG-ABCD-EFGH-JKLM-NPQR",
    "domain": "demo.example.com",
    "status": "active",
    "status_text": "正常",
    "permanent": false,
    "activated_at": "2026-10-27 20:18:00",
    "expires_at": "2027-10-27 20:18:00",
    "days_left": 365,
    "max_activations": 1,
    "activation_count": 1,
    "verify_interval_minutes": 1,
    "offline_grace_hours": 72,
    "server_ip": "38.76.166.40",
    "server_ip_version": "IPv4",
    "server_time": "2026-10-27 20:18:00",
    "sign": "…"
  }
}
GET 方式适合脚本或链接直接激活:https://api.idcxb.com/api/v1/activate?license_key=...&domain=...,返回同样的 JSON。

6. 在线校验

POST https://api.idcxb.com/api/v1/verify

建议每 1 分钟调用一次。license_key 与 domain 都必填, 服务端会同时核对域名和请求出口 IP,任一项不一致即返回 1014。

curl -X POST "https://api.idcxb.com/api/v1/verify" \
  -d "license_key=IDCG-ABCD-EFGH-JKLM-NPQR" \
  -d "domain=demo.example.com"
{
  "code": 0,
  "message": "ok",
  "data": {
    "license_key": "IDCG-ABCD-EFGH-JKLM-NPQR",
    "domain": "demo.example.com",
    "status": "active",
    "status_text": "正常",
    "permanent": false,
    "expires_at": "2027-10-27 20:18:00",
    "days_left": 365,
    "max_activations": 1,
    "activation_count": 1,
    "verify_interval_minutes": 1,
    "offline_grace_hours": 72,
    "server_ip": "38.76.166.40",
    "server_ip_version": "IPv4",
    "server_time": "2026-10-27 20:18:00",
    "sign": "…"
  }
}
校验失败时不要立刻停机。先看 offline_grace_hours,在宽限期内继续运行并重试。

7. 解绑

POST https://api.idcxb.com/api/v1/deactivate

迁移服务器或更换域名时调用,释放一个域名名额。license_key 与 domain 都必填。

curl -X POST "https://api.idcxb.com/api/v1/deactivate" \
  -d "license_key=IDCG-ABCD-EFGH-JKLM-NPQR" \
  -d "domain=demo.example.com"

成功时返回 code=0,message 为「解绑成功」。 子域名需要单独绑定与解绑,解绑时按域名精确匹配。

9. 授权回调(callback)

在链接后面加一个 callback,授权成功后会 302 跳回这个地址, 并把授权信息一并带过去。你的程序在那个入口验签、落库即可,客户全程不用复制粘贴。

# 授权成功后跳回 https://demo.example.com/license-callback
https://api.idcxb.com/activate?key=IDCG-ABCD-EFGH-JKLM-NPQR&domain=demo.example.com&callback=https://demo.example.com/license-callback
参数 说明
license_code0 表示成功
license_key授权码
domain本次绑定的域名
payloadbase64 后的授权信息 JSON(含到期时间、绑定上限、功能列表等)
sign对 payload 的 HMAC-SHA256,用签名盐值验签

客户程序端的接收示例:

// /license-callback.php —— 放在你自己的站点上
$payload = $_GET['payload'] ?? '';
$sign    = $_GET['sign'] ?? '';

// 1. 验签,防止参数被篡改
$expect = hash_hmac('sha256', $payload, '你的签名盐值');
if (! hash_equals($expect, $sign)) {
    exit('签名校验失败');
}

// 2. 解开授权信息
$license = json_decode(base64_decode($payload), true);

// 3. 写入自己的配置或数据库
file_put_contents(__DIR__ . '/license.json', json_encode($license, JSON_UNESCAPED_UNICODE));

header('Location: /admin?licensed=1');
callback 只允许跳回与 domain 同域的地址(含子域),填别的域名会被忽略, 以免被当成开放重定向跳板;授权失败时不跳转,直接在本页显示原因,方便改完重试。

10. 请求参数

参数 必填 说明
license_key 是 授权码,形如 IDCG-XXXX-XXXX-XXXX-XXXX,大小写与连字符会被自动归一化
domain 是 当前部署域名,协议、端口、www. 会被自动去掉;子域名需要单独绑定
machine_code 否 机器码,便于排查同一授权在多台机器上的使用情况

11. 调用示例

激活(PHP cURL):

// 首次部署时调用一次,成功后把结果缓存到本地
$payload = [
    'license_key' => 'IDCG-ABCD-EFGH-JKLM-NPQR',
    'domain'      => $_SERVER['HTTP_HOST'],
];

$ch = curl_init('https://api.idcxb.com/api/v1/activate');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($payload),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 8,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);

if (($res['code'] ?? -1) !== 0) {
    die('授权校验失败:' . ($res['message'] ?? '未知错误'));
}
// $res['data'] 内含到期时间、可绑定数量、服务器 IP 等

定时校验(建议放进计划任务,每 1 分钟一次):

// 校验失败时不要立刻停机,先看离线宽限期
$res = post('https://api.idcxb.com/api/v1/verify', $payload);

if (($res['code'] ?? -1) === 0) {
    cache_set('license_ok_at', time());
} elseif (time() - cache_get('license_ok_at') > 72 * 3600) {
    // 超出 72 小时宽限期,才真正停用
    die('授权已失效:' . $res['message']);
}

12. 返回码

code含义建议处理
0校验通过正常放行
1001缺少必要参数检查 license_key 与 domain
1002授权码不存在提示用户核对授权码
1003授权已禁用联系管理员
1004授权已吊销不可恢复,需重新申请授权
1005授权已过期联系管理员续期
1006绑定数量已达上限先在用户中心解绑旧域名
1007域名未绑定先调用 activate
1011域名已被其它授权占用更换域名或先解绑
1012请求过于频繁降低校验频率
1013未绑定域名与服务器 IP提示用户先绑定域名与 IP 再使用授权码
1014服务器 IP 与绑定不一致在用户中心重新绑定该域名,更新服务器 IP
除 HTTP 429 外,业务错误仍返回 200,必须判断 JSON 里的 code,不能只看 HTTP 状态码。429 表示触发 IP 限流,请按 Retry-After 退避后重试。

13. 响应验签

返回体的 data 中带有一个 sign 字段,是对除 sign 外所有字段 按键名排序后做 JSON 编码、再用签名盐值做 HMAC-SHA256 得到的。客户端用同样的方式重算一次即可确认结果未被篡改。

function verifySign(array $data, string $salt): bool
{
    $sign = $data['sign'] ?? '';
    unset($data['sign']);
    ksort($data);

    $expect = hash_hmac('sha256', json_encode($data, JSON_UNESCAPED_UNICODE), $salt);

    return hash_equals($expect, $sign);
}
验签失败说明返回体可能被代理或中间人修改,请丢弃本次结果并按失败处理。

14. 接入检查清单

  • 激活成功后把 data 缓存到本地,避免每次启动都重新激活。
  • 校验间隔使用接口返回的 verify_interval_minutes,不要写死。
  • 校验失败先走 offline_grace_hours 宽限,不要立即停机。
  • 每次成功响应都验签,确认 sign 与本地重算结果一致。
  • 迁移服务器前先调用 /deactivate 释放旧域名,避免触发绑定上限。
  • 服务器 IP 以调用方出口 IP 为准,客户端无需读取网卡;绑定域名时需确保域名解析到该 IP。
  • 子域名需要单独绑定,根域名不会自动覆盖子域名。
  • 日志里不要记录完整授权码,展示时至少打码中间两段。

15. 常见问题

返回 1006「绑定数量已达上限」怎么办?

先到用户中心解绑不再使用的域名,或联系管理员提高该授权的绑定上限,然后重新调用激活。

换了域名,需要重新申请授权吗?

不需要。先调用 /deactivate 解绑旧域名,再用新域名调用 /activate。

子域名需要单独绑定吗?

需要。根域名与子域名按完全一致的域名分别校验,使用子域名时请单独绑定该子域名。

校验接口偶尔超时,会不会导致客户停机?

不会。按 offline_grace_hours 继续运行并重试即可,只有超过宽限期仍未校验成功才判定失效。

可以只做本地校验、不连服务器吗?

不建议。授权状态、续期和域名变更都以服务端为准,长期离线会错过状态变化。

服务器 IP 变了,需要重新绑定吗?

需要。授权会同时校验域名与服务器 IP,IP 变化后 /verify 会返回 1014;到用户中心重新绑定该域名(点「检测」或填写新 IP)即可更新基准。

检测到的是 CDN 或代理 IP,怎么办?

授权绑定要求域名解析结果与服务器 IP 一致,CDN 节点 IP 无法作为绑定基准。请为授权接口使用直接解析到源站 IP 的域名,或调整解析后再绑定。

16. 公开授权查询

GET https://api.idcxb.com/api/v1/check?q=example.com

无需登录即可核验授权真伪,与官网「授权查询」页面同一套判断逻辑,适合放在客户官网、帮助中心或工单页。 传域名会精确匹配已绑定的域名,传服务器 IP 会匹配绑定记录里的 IP,传授权码则直接查该授权。 每个 IP 每分钟 30 次。

参数必填说明
q是域名、服务器 IP 或授权码,3–128 个字符;授权码可省略横线
curl "https://api.idcxb.com/api/v1/check?q=example.com"
{
  "code": 0,
  "message": "ok",
  "data": {
    "query": "example.com",
    "type": "domain",
    "found": true,
    "license": {
      "masked_key": "IDCG-****-****-****-8F2K",
      "status": "active",
      "status_label": "授权有效",
      "status_note": null,
      "expires_at": "2027-10-27 20:18:00",
      "days_left": 363,
      "max_activations": 3,
      "active_count": 1,
      "matched_domain": "example.com",
      "covered_by": null,
      "binding_text": "example.com"
    }
  }
}
status含义建议提示
active授权有效可正常使用
unbound已签发但未绑定域名引导用户到用户中心绑定
pending未激活提示先完成激活
expired已过期引导续期
disabled已禁用联系管理员
revoked已吊销不可恢复,需重新申请授权
查询不到时返回 found: false(HTTP 200),不区分「授权不存在」与「域名未绑定」,避免被枚举; 参数不合法返回 42201。接口结果实时查询,请勿在前端长时间缓存。