Drupal 9:如何仅允许特定域名访问页面或文件
仅允许特定域名访问Drupal文件或页面(无需PHP Filter模块)
不用PHP Filter模块的话,推荐以下几种安全高效的方案:
1. 服务器层面配置(.htaccess)
这是最轻量化的方案,直接通过Apache的mod_rewrite规则限制来源域名,不依赖Drupal模块,性能最优。
在你的Drupal根目录的.htaccess文件中添加以下规则(按需修改路径和允许的域名):
# 启用Rewrite引擎 RewriteEngine On # 定义允许访问的域名(支持http/https,带或不带www) RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC] RewriteCond %{HTTP_REFERER} !^https?://(www\.)?test\.com/ [NC] # 指定需要保护的路径(比如私有文件目录或特定页面路径) RewriteCond %{REQUEST_URI} ^/sites/default/files/protected/ [NC] # 不符合条件则返回403禁止访问 RewriteRule ^ - [F,L]
说明:
[NC]表示不区分大小写^/sites/default/files/protected/替换成你实际要保护的文件或页面路径- 若要保护整个站点,可去掉这条路径匹配规则
2. 自定义Drupal模块(适用于Drupal 8/9/10)
如果需要更灵活的控制(比如针对特定内容类型、角色结合域名限制),可以编写简单的自定义模块,完全避开PHP Filter的安全风险。
示例1:保护私有文件
在自定义模块的.module文件中实现hook_file_download:
function my_custom_module_file_download($uri) { // 只保护public://protected/目录下的文件(可替换为私有文件路径) if (strpos($uri, 'public://protected/') === 0) { $allowed_domains = ['example.com', 'test.com']; $referer = \Drupal::request()->headers->get('Referer'); // 无Referer直接禁止 if (!$referer) { return -1; } $parsed_referer = parse_url($referer); $referer_host = $parsed_referer['host'] ?? ''; // 检查域名是否在允许列表(支持带www的情况) $is_allowed = in_array($referer_host, $allowed_domains) || in_array('www.' . $referer_host, $allowed_domains); if (!$is_allowed) { return -1; // 返回403禁止访问 } } }
示例2:保护特定页面/内容类型
实现hook_node_access来限制特定内容类型的页面访问:
function my_custom_module_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) { // 仅针对'protected_page'内容类型的查看操作 if ($node->getType() === 'protected_page' && $op === 'view') { $allowed_domains = ['example.com', 'test.com']; $referer = \Drupal::request()->headers->get('Referer'); if (!$referer) { return \Drupal\Core\Access\AccessResult::forbidden(); } $parsed_referer = parse_url($referer); $referer_host = $parsed_referer['host'] ?? ''; $is_allowed = in_array($referer_host, $allowed_domains) || in_array('www.' . $referer_host, $allowed_domains); return $is_allowed ? \Drupal\Core\Access\AccessResult::neutral() : \Drupal\Core\Access\AccessResult::forbidden(); } return \Drupal\Core\Access\AccessResult::neutral(); }
注意:Referer头可能被浏览器禁用或篡改,若需要绝对安全的限制,建议结合IP白名单或用户登录验证。
内容的提问来源于stack exchange,提问作者pri2712
相关产品推荐
相关产品推荐

