簡體   English   中英

php $ _SERVER ['HTTP_HOST']始終是同一個域,無論我從哪個域請求

[英]php $_SERVER['HTTP_HOST'] is always same domain no matter from which domain i request

現在,例如,我有以下域:

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。

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 On才能存在。 另請參見gethostbyaddr()。

我終於找到了解決自己問題的答案。

答案是向引用服務器中的真實域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;
    }
}

所以基本上有2個功能,

  1. 從更新服務器使用cURL請求生成令牌,然后更新服務器返回該令牌並將其創建為文件。
  2. 從服務器端下載,但在檢查令牌是否存在並在請求的cURL域上有效之前,令牌只能使用1次-使用后立即從服務器端數據庫中將其刪除。

為每個請求重新生成相同的令牌,並在完成請求后刪除令牌。

沒有人可以用這種邏輯欺騙你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM