'IDCG-XXXX-XXXX-XXXX-XXXX', * 'domain' => 'demo.example.com', * 'version' => '1.0.0', * ]); * if (($res['code'] ?? -1) !== 0) { exit($res['message'] ?? '授权校验失败'); } * * 接口地址可用常量 IDCGO_LICENSE_ENDPOINT 覆盖,默认 https://api.idcxb.com/api/v1 */ if (! defined('IDCGO_LICENSE_ENDPOINT')) { define('IDCGO_LICENSE_ENDPOINT', 'https://api.idcxb.com/api/v1'); } if (! function_exists('licenseRequest')) { /** * 调用一个授权接口并返回统一结构:['code' => int, 'message' => string, 'data' => mixed] * * @param string $path 接口路径,如 /activate、/verify、/deactivate、/ping、/ip、/version/{slug} * @param array $data 请求参数(POST 走 JSON,GET 走查询串) * @param string|null $method 默认按路径自动判断:ping / ip / version 为 GET,其余 POST * @param int $timeout 超时秒数 */ function licenseRequest(string $path, array $data = [], ?string $method = null, int $timeout = 10): array { $path = '/' . ltrim($path, '/'); $method = strtoupper($method ?: (preg_match('#^/(ping|ip|version)(/|$)#', $path) ? 'GET' : 'POST')); $url = rtrim(IDCGO_LICENSE_ENDPOINT, '/') . $path; if ($method === 'GET' && $data !== []) { $url .= (str_contains($url, '?') ? '&' : '?') . http_build_query($data); } $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => $timeout, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', ], CURLOPT_USERAGENT => 'IDCGo-License-SDK/1.0', ]); if ($method !== 'GET') { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); } $raw = curl_exec($ch); $error = curl_error($ch); $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($raw === false) { return ['code' => -1, 'message' => '网络请求失败:' . $error, 'data' => null]; } $json = json_decode($raw, true); if (! is_array($json) || ! array_key_exists('code', $json)) { return [ 'code' => -1, 'message' => '响应解析失败(HTTP ' . $status . ')', 'data' => $raw, ]; } return $json; } } if (! function_exists('licenseVerifySign')) { /** * 校验响应中的 sign 字段,防止中间人篡改。 * 签名算法:HMAC-SHA256(json_encode(data, JSON_UNESCAPED_UNICODE), LICENSE_SIGN_SALT) * * @param array $data 响应里的 data 节点 * @param string $salt 与服务端一致的 LICENSE_SIGN_SALT */ function licenseVerifySign(array $data, string $salt): bool { $sign = (string) ($data['sign'] ?? ''); if ($sign === '') { return false; } unset($data['sign']); $expected = hash_hmac( 'sha256', json_encode($data, JSON_UNESCAPED_UNICODE), $salt ); return hash_equals($expected, $sign); } }