在没有 .htaccess 的 Drupal 站点上设置基本身份验证

基本 HTTP 身份验证是一种简单的身份验证机制,用于防止访问服务器上的站点或目录。它绝不是最安全的身份验证机制,但它通常用于临时站点以防止不必要的访问。这是防止搜索引擎机器人爬取暂存站点的好方法,这是不可取的,因为它会导致暂存站点页面出现在搜索引擎结果中。

通常的设置方法是创建一个 .htaccess 来设置身份验证并引用一个 .htpasswd 文件来创建用户名和密码详细信息。这可能意味着编辑 .htaccess 文件以正确设置密码。不幸的是,这会创建一个不应添加到存储库的 .htaccess 文件,因为这意味着在部署代码时,实时站点也将受到密码保护。

解决此问题的最佳方法是将身份验证机制放入您的 Drupalsettings.php文件中。这可以防止身份验证机制被传递到他的实时站点。

这里要做的第一件事是在你的 Apache 配置中设置一个环境变量。稍后将在脚本中使用它来检测是否需要密码。这是确保声明站点是唯一受身份验证代码影响的站点的好方法。

SetEnv SET_PASSWORD "true"

您需要将一个规则添加到 Drupal .htaccess 文件中,但如果它恰好部署到实时站点,则不会导致任何不需要的副作用。这需要放在 .htaccess 文件的末尾,以便index.php正确触发正常的 Drupal规则。

RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]

此处的“E”标志使用经过身份验证的用户详细信息设置环境变量,以便我们可以在 PHP 中读取它。“L”标志意味着如果此规则触发,则不会处理其他重写规则。

现在将以下内容添加到您的settings.php文件中。这是密码验证工作所需的完整代码。您可以通过更改脚本顶部的变量来更改用户名和密码。

if (php_sapi_name() != 'cli' && getenv('SET_PASSWORD') !== FALSE) {
  $username = 'username';
  $password = 'password';
 
  // PHP-CGI 修复。
  $a = base64_decode(substr($_SERVER["REMOTE_USER"], 6));
  if ((strlen($a) == 0) || (strcasecmp($a, ":") == 0)) {
    header('WWW-Authenticate: Basic realm="Private"');
    header('HTTP/1.0 401 Unauthorized');
  }
  else {
    list($name, $pass) = explode(':', $a);
    $_SERVER['PHP_AUTH_USER'] = $name;
    $_SERVER['PHP_AUTH_PW'] = $pass;
  }
 
  if (!(isset($_SERVER['PHP_AUTH_USER']) && ($_SERVER['PHP_AUTH_USER'] == $username && $_SERVER['PHP_AUTH_PW'] == $password))) {
    header('WWW-Authenticate: Basic realm="This site is protected"');
    header('HTTP/1.0 401 Unauthorized');
    // 用户按下取消时的回退页面。
    echo '<html><head></head><body><h1>Access denied</h1></body></html>';
    exit;
  }
}

一切就绪后,您将在下次打开网站时看到登录提示。

如果您不想设置 Apache 变量,则可以使用此替代语法来检测站点。下面的 if 语句意味着如果站点 URL 是 staging.example.com,则身份验证会触发。

if (php_sapi_name() != 'cli' && isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] == 'staging.example.com') {
}

添加这些检查的好处是,即使代码确实进入了实时框,它也不会导致错误。但是,如果您不想将其添加到settings.php文件中,那么还有一种替代方法。Drupalsettings.php文件可以包含一些用于缓存设置和类似内容的低级配置,因此有时会将其写入存储库以包含这些设置。如果您还将以下几行添加到您的settings.php文件中,则将包含一个名为 local.settings.php 的本地文件。

// 覆盖此文件中的设置
if (file_exists('./'. conf_path() .'/local.settings.php')) {
  include_once './'. conf_path() .'/local.settings.php';
}

有了这个,您可以将身份验证机制放入 local.settings.php 文件中,并且它永远不会部署到实时站点。