php $ _SERVER ['HTTP_HOST']永远是同一个域,无论我请求哪个域

时间:2018-03-23 13:42:26

标签: php apache ubuntu

目前我有这样的域名:

domain1.com domain2.com domain3.com domain4.com

我尝试使用domain1.com,domain2.com,domain3.com domain4.com的cURL并阻止cURL请求。

domain1.com上的示例代码文件:

try{
  $ch = curl_init();
  if (FALSE === $ch){
    throw new Exception('failed to initialize');
  }
  curl_setopt($ch, CURLOPT_URL,"http://domain4.com/test3.php?v=1.4");
  curl_setopt($ch, CURLOPT_POST, TRUE);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  $p_result = curl_exec($ch);
  var_dump($p_result);
  print_r($p_result);
  if (FALSE === $p_result) {
    throw new Exception(curl_error(), curl_errno());
    curl_close($ch);
  } else{
    curl_close($ch);
    return $p_result;
  }
}catch(Exception $e) {
  trigger_error(sprintf('Curl failed with error #%d: %s',$e->getCode(), $e->getMessage()),E_USER_ERROR);
}

domain4.com上的示例代码文件:

  $domains = array("domain1.com"); //blacklisted

  $domainIsValid = array_filter($domains, function ($var) use ($_SERVER) {
        return strpos($var, $_SERVER['HTTP_HOST']) !== false;
    });

$_SERVER['HTTP_HOST'] // is always domain1.com even if i request from domain3.com

我错过了什么吗?是Apache服务器配置吗?

主机:带有Apache服务器的DigitalOcean Ubuntu 16.04。

2 个答案:

答案 0 :(得分:0)

PHP文档说:http://php.net/manual/en/reserved.variables.server.php

'HTTP_HOST'  Contents of the Host: header from the current request, if there is one.

您可能从所有域发送相同的标头。

我认为REMOTE_ADDR或REMOTE_HOST更适合用于黑名单,因为HTTP标头很容易被欺骗。

编辑:注意:您的Web服务器必须配置为创建REMOTE_HOST变量。例如,在Apache中,您需要在httpd.conf中使用HostnameLookups才能存在。另见gethostbyaddr()。

答案 1 :(得分:0)

我终于找到了自己的答案。

答案是向referer中的真实域HTTP_HOST发送cURL请求到更新服务器, 在更新服务器中生成令牌后:

     $token =  md5(uniqid($domain, true));//Create token
     $stmt4 = $dbh->prepare("INSERT INTO tokens (domain) VALUES (?)");//Store just to know from where the request for later use
     $stmt4->bindParam(1, $dm);
                                                // insert one row       
     $dm =  json_encode(array('domain'=>$domain,'token'=>$token),true);                    
     $stmt4->execute();

然后根据域请求创建一个带有该令牌返回的文件,然后检查令牌是否在请求域上找到它可以继续更新并删除令牌。

    $exists = checkRemoteFile($domain.'/'.$token);
    if ($exists) {
        echo "found";   
    } else{
      /*  header("HTTP/1.1 401 Unauthorized");
        exit();*/
    }

function checkRemoteFile($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if(curl_exec($ch)!==FALSE)
    {
        return true;
    }
    else
    {
        return false;
    }
}

所以基本上有两个功能,

  1. 使用来自更新服务器的cURL请求生成令牌,更新服务器返回令牌并将其创建为文件。
  2. 从服务器端下载,但在检查令牌是否存在且在请求cURL域上是否有效之前,Token只能使用一次 - 使用后立即从服务器端的数据库中删除它。
  3. 为每个请求重新生成令牌,并在完成请求后删除令牌。

    没有人可以用这种逻辑欺骗你。