当前位置:首页 > 云服务器 > 正文

如何用PHP限制域名访问? | PHP安全配置优化指南

在PHP中限制域名访问可以通过检查HTTP请求中的Host头来实现,以下是几种实现方法:


方法1:直接比较域名(推荐)

// 允许访问的域名列表(不含端口) $allowedDomains = [ 'example.com', 'www.example.com', 'app.example.com' ]; // 获取当前请求的域名(自动去除端口号) $currentHost = strtolower(explode(':', $_SERVER['HTTP_HOST'])[0]); // 验证域名 if (!in_array($currentHost, $allowedDomains)) { http_response_code(403); // 禁止访问 exit('Access Denied: Invalid domain'); } // 后续正常代码...


方法2:支持通配符的子域名匹配

$allowedPatterns = [ 'example.com', '*.example.com' // 允许所有子域名 ]; $currentHost = strtolower(explode(':', $_SERVER['HTTP_HOST'])[0]); $allowed = false; foreach ($allowedPatterns as $pattern) { if ($pattern === $currentHost) { $allowed = true; break; } // 处理通配符 *.example.com if (strpos($pattern, '*') !== false) { $regex = '/^' . str_replace('*', '[^.]+', preg_quote($pattern, '/')) . '$/'; if (preg_match($regex, $currentHost)) { $allowed = true; break; } } } if (!$allowed) { http_response_code(403); exit('Invalid domain'); }


方法3:通过.htaccess限制(更高效)

在网站根目录创建/修改.htaccess文件:

RewriteEngine On RewriteCond %{HTTP_HOST} !^(www.)?example.com$ [NC] RewriteCond %{HTTP_HOST} !^app.example.com$ [NC] RewriteRule ^ - [F] # 返回403禁止访问


注意事项:

  1. 安全性

    如何用PHP限制域名访问? | PHP安全配置优化指南 第1张

    • Host头可被杜撰,敏感操作需额外验证(如Session/Cookie)
    • 此方法主要用于防止用户通过非常用域名访问
  2. 特殊场景处理

    如何用PHP限制域名访问? | PHP安全配置优化指南 第2张

    // 处理直接通过IP访问的情况 if (!isset($_SERVER['HTTP_HOST']) || is_numeric(str_replace('.', '', $_SERVER['HTTP_HOST']))) { exit('Domain access only'); }

  3. 端口处理

    如何用PHP限制域名访问? | PHP安全配置优化指南 第3张

    • 代码中已自动剥离端口(如 example.com:8080 → example.com)
    • 如需允许特定端口,需在允许列表中添加带端口的域名
    • 完整示例代码:

      <?php // config.php - 域名验证 $allowed = [ 'example.com', 'www.example.com', '*.app.example.com' ]; $host = $_SERVER['HTTP_HOST'] ?? ''; if (empty($host)) die('Invalid request'); // 剥离端口 $host = strtolower(explode(':', $host)[0]); $valid = false; foreach ($allowed as $domain) { // 完全匹配 if ($domain === $host) { $valid = true; break; } // 通配符匹配 if (strpos($domain, '*') !== false) { $pattern = '/^' . str_replace('*', '.*', preg_quote($domain)) . '$/'; if (preg_match($pattern, $host)) { $valid = true; break; } } } if (!$valid) { http_response_code(403); include('forbidden.html'); // 自定义错误页 exit; } // 后续业务代码... ?>


      常见问题解决:

      1. 本地开发绕过

      2. 负载均衡场景

        • 如果使用CDN/代理,检查X-Forwarded-Host头: $host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? $_SERVER['HTTP_HOST'];
        • 大小写问题

          • 使用strtolower()统一转为小写比较
          • 选择最适合你项目需求的方法,通常推荐使用.htaccess进行服务器级限制以减少PHP解析开销。

0