You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Widget与Analytics嵌入脚本的认证机制及PHP可信域名验证咨询

防止Widget/Analytics脚本被盗用的方案 & PHP域名验证方法

一、防止脚本被未授权网站滥用的核心方案

客户端的任何信息都能被篡改,所以必须客户端校验+后端强验证结合,以下是实际可用的手段:

  • 绑定公钥到授权域名:用户配置账号时,要求填写允许使用该Widget的域名列表(比如example.com、blog.example.com),后端将公钥和域名列表关联存储。当Widget脚本加载时,前端先获取当前页面的window.location.host做一层客户端校验(不匹配就直接停止渲染);同时前端向后端请求核心数据时,带上当前域名和公钥,后端校验该公钥对应的允许域名列表里是否包含这个域名,不匹配就拒绝返回数据。
  • 请求签名验证:前端Widget用公钥+当前域名+时间戳,通过HMAC算法生成签名(比如HMAC-SHA256),向后端请求时带上公钥、域名、时间戳和签名。后端用对应私钥+存储的允许域名+时间戳重新计算签名,对比一致才通过验证。时间戳还能防止重放攻击(比如限制请求在5分钟内有效)。
  • Referer头校验(辅助防线):后端接收Widget的请求时,先检查Referer头的域名是否在授权列表里。虽然Referer可以被伪造,但作为低成本的第一道过滤,能挡住大部分非技术型盗用。
  • 动态生成嵌入代码:不给用户固定的公钥脚本,而是每次生成嵌入代码时,带上和用户域名绑定的临时token,或者让用户通过后端接口动态获取嵌入脚本,脚本里的标识和当前请求的域名绑定,过期失效。

二、PHP中验证请求来源域名的方法

PHP里没有绝对安全的单一步骤,必须结合多种手段:

1. 解析并校验Referer头

// 先检查Referer是否存在
if (!isset($_SERVER['HTTP_REFERER'])) {
    http_response_code(403);
    exit('Unauthorized');
}

// 解析Referer获取域名
$refererInfo = parse_url($_SERVER['HTTP_REFERER']);
if (!$refererInfo || !isset($refererInfo['host'])) {
    http_response_code(403);
    exit('Invalid referer');
}

// 允许的域名列表(从数据库或配置文件读取)
$allowedDomains = ['example.com', 'blog.example.com'];

// 校验域名是否在允许列表
if (!in_array($refererInfo['host'], $allowedDomains)) {
    http_response_code(403);
    exit('Domain not allowed');
}

⚠️ 注意:HTTP_REFERER可能为空(比如浏览器隐私设置禁用、直接访问接口),所以不能单独依赖这个,必须和签名验证结合。

2. 结合签名验证(安全级别更高)

假设前端发送的请求参数包含public_key、domain、timestamp、signature:

// 从请求中获取参数
$publicKey = $_GET['public_key'] ?? '';
$requestDomain = $_GET['domain'] ?? '';
$timestamp = $_GET['timestamp'] ?? '';
$signature = $_GET['signature'] ?? '';

// 1. 检查时间戳是否有效(防止重放攻击,限制5分钟内)
if (time() - intval($timestamp) > 300) {
    http_response_code(403);
    exit('Request expired');
}

// 2. 从数据库获取该公钥对应的私钥和允许域名列表(示例用模拟数据)
$storedData = [
    'private_key' => 'your-stored-private-key',
    'allowed_domains' => ['example.com', 'blog.example.com']
];

// 3. 校验请求域名是否在允许列表
if (!in_array($requestDomain, $storedData['allowed_domains'])) {
    http_response_code(403);
    exit('Domain not allowed');
}

// 4. 重新计算签名并对比
$dataToSign = $publicKey . $requestDomain . $timestamp;
$calculatedSignature = hash_hmac('sha256', $dataToSign, $storedData['private_key']);

if ($calculatedSignature !== $signature) {
    http_response_code(403);
    exit('Invalid signature');
}

// 验证通过,处理请求
echo 'Valid request';

3. 注意事项

  • 永远不要信任客户端传来的域名参数,必须从请求头或签名里间接验证。
  • 允许的域名建议用精确匹配,或者支持通配符(比如*.example.com),但通配符要注意校验逻辑(避免误匹配example.com.cn这类域名)。
  • 私钥要妥善存储在后端,绝对不能暴露给前端。

内容的提问来源于stack exchange,提问作者RDU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:12:38