域名验证文档

Web 应用域名授权验证指南

功能说明

域名验证功能用于保护 Web 应用,确保只有已授权的域名才能正常使用系统。适用于 SaaS 平台、网站系统等场景。

验证流程

1

在管理后台添加域名

管理员在【域名管理】中添加需要授权的域名

2

应用启动时调用 API 验证

应用通过 API 验证当前域名是否已授权(需签名)

3

根据返回结果放行或拦截

验证通过则正常运行,失败则显示未授权提示

密钥说明

product_key(产品ID)

在【产品管理】列表中查看

示例: "1"

secret_key(产品密钥)

在【产品管理 → 编辑】中查看,48位字符串

用于 API 请求签名

timestamp + sign(签名)

每次请求必须包含

签名算法见集成文档

验证接口

POST /api/domain-verify.php

验证域名是否已授权。请求方式为 POST + JSON,需携带签名。

请求参数:

参数类型必填说明
product_keyint必填产品ID
timestampint必填当前Unix时间戳(秒)
signstring必填HMAC-SHA256签名(使用 secret_key)
domainstring必填要验证的域名

域名授权成功返回:

{
  "success": true,
  "code": 0,
  "message": "域名已授权",
  "data": {
    "domain": "example.com",
    "authorized": true,
    "code": "",
    "expire_time": 1735689600
  }
}

域名未授权返回:

{
  "success": false,
  "code": 403,
  "message": "域名未授权",
  "data": {
    "domain": "example.com",
    "authorized": false
  }
}

域名已过期返回:

{
  "success": false,
  "code": 403,
  "message": "域名授权已过期",
  "data": {
    "domain": "example.com",
    "authorized": false,
    "expire_time": 1735689600
  }
}

签名算法

域名验证同样需要 HMAC-SHA256 签名,算法与用户验证接口一致:

1

构建参数:{"product_key": 1, "timestamp": 1735600000, "domain": "example.com"}

2

过滤空值后按 key 字典序排列,拼接为:domain=example.com&product_key=1×tamp=1735600000

3

计算:HMAC-SHA256(secret_key, signStr) 得到签名字符串

4

将签名添加到请求的 sign 字段中

集成代码示例

PHP 验证示例(服务端推荐):

<?php
/**
 * 域名授权验证 - 放在应用入口文件开头
 */
function verifyDomainAuth() {
    $apiUrl = 'https://your-domain.com/api/domain-verify.php';
    $secretKey = 'your_secret_key_48chars';
    $productId = 1;

    // 获取当前域名
    $currentDomain = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];

    // 构建参数
    $params = [
        'product_key' => $productId,
        'timestamp'   => time(),
        'domain'      => $currentDomain,
    ];

    // 生成签名
    $filtered = [];
    foreach ($params as $k => $v) {
        if ($k === 'sign') continue;
        if ($v !== null && $v !== '') {
            $filtered[$k] = (string)$v;
        }
    }
    ksort($filtered);
    $signStr = implode('&', array_map(
        fn($k, $v) => "$k=$v",
        array_keys($filtered), $filtered
    ));
    $params['sign'] = hash_hmac('sha256', $signStr, $secretKey);

    // 发送请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // 网络异常时放行(避免服务器宕机导致所有站点不可用)
    if ($response === false || $httpCode !== 200) {
        return true;
    }

    $result = json_decode($response, true);
    return isset($result['success']) && $result['success'] === true;
}

// 在应用入口调用
if (!verifyDomainAuth()) {
    http_response_code(403);
    die('<h1>域名未授权</h1><p>请联系管理员获取授权</p>');
}

JavaScript/Node.js 验证示例:

/**
 * 域名授权验证 - Node.js 服务端中间件
 */
async function verifyDomainAuth(secretKey, productId) {
    const apiUrl = 'https://your-domain.com/api/domain-verify.php';
    const currentDomain = process.env.HOST || 'example.com';

    // 构建参数
    const params = {
        product_key: productId,
        timestamp: Math.floor(Date.now() / 1000),
        domain: currentDomain,
    };

    // 生成签名(Node.js)
    const crypto = require('crypto');
    const filtered = Object.entries(params)
        .filter(([k, v]) => v !== null && v !== '')
        .sort(([a], [b]) => a.localeCompare(b));
    const signStr = filtered.map(([k, v]) => `${k}=${v}`).join('&');
    params.sign = crypto
        .createHmac('sha256', secretKey)
        .update(signStr)
        .digest('hex');

    // 发送请求
    try {
        const response = await fetch(apiUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(params),
        });
        const result = await response.json();
        return result.success === true;
    } catch (error) {
        // 网络异常时放行
        return true;
    }
}

// Express 中间件示例
app.use(async (req, res, next) => {
    const authorized = await verifyDomainAuth(
        'your_secret_key_48chars', 1
    );
    if (!authorized) {
        return res.status(403).send('<h1>域名未授权</h1>');
    }
    next();
});

Python 验证示例:

import hashlib, hmac, time, json, urllib.request

def verify_domain():
    api_url = 'https://your-domain.com/api/domain-verify.php'
    secret_key = 'your_secret_key_48chars'
    product_id = 1
    domain = 'example.com'  # 替换为当前域名

    # 构建参数
    params = {
        'product_key': product_id,
        'timestamp': int(time.time()),
        'domain': domain,
    }

    # 生成签名
    filtered = {k: str(v) for k, v in params.items() if v}
    sign_str = '&'.join(f"{k}={v}" for k, v in sorted(filtered.items()))
    sign = hmac.new(
        secret_key.encode(), sign_str.encode(), hashlib.sha256
    ).hexdigest()
    params['sign'] = sign

    # 发送请求
    try:
        req = urllib.request.Request(
            api_url,
            data=json.dumps(params).encode(),
            headers={'Content-Type': 'application/json'},
        )
        with urllib.request.urlopen(req, timeout=5) as resp:
            result = json.loads(resp.read())
            return result.get('success', False)
    except Exception:
        return True  # 网络异常时放行

if not verify_domain():
    print("域名未授权")
    exit(1)

注意事项