簡體   English   中英

如何繞過訪問控制允許來源?

[英]how to bypass Access-Control-Allow-Origin?

我正在他們設置的平台上對我自己的服務器進行 ajax 調用以防止這些 ajax 調用(但我需要它從我的服務器獲取數據以顯示從我的服務器數據庫中檢索到的數據)。 我的 ajax 腳本正在運行,它可以將數據發送到我服務器的 php 腳本以允許它進行處理。 但是它無法取回已處理的數據,因為它被"Access-Control-Allow-Origin"阻止

我無權訪問該平台的源代碼/核心。 所以我不能刪除它不允許我這樣做的腳本。 (P/SI 使用了 Google Chrome 的 Console 發現了這個錯誤)

Ajax代碼如下所示:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });

或者上面的 ajax 腳本是否有等效的JSON代碼? 我認為JSON是允許的。

我希望有人能幫助我。

把它放在retrieve.php之上:

header('Access-Control-Allow-Origin: *');

請注意,這會有效地禁用 CORS 保護,並使您的用戶暴露在攻擊之下。 如果您不完全確定需要允許所有來源,則應將其鎖定為更具體的來源:

header('Access-Control-Allow-Origin: https://www.example.com');

請參閱以下堆棧答案以更好地理解Access-Control-Allow-Origin

https://stackoverflow.com/a/10636765/413670

好的,但你們都知道 * 是一個通配符並允許來自每個域的跨站點腳本?

您想為每個Access-Control-Allow-Origin站點發送多個Access-Control-Allow-Origin標頭 - 但不幸的是,官方不支持發送多個Access-Control-Allow-Origin標頭,或放入多個來源。

如果允許,您可以通過檢查來源並在標頭中發回該來源來解決此問題:

$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}

這樣就安全多了。 您可能想要編輯匹配項並將其更改為帶有一些正則表達式或類似內容的手動功能。 至少這只會發回 1 個標頭,您將確定它是請求來自的標頭。 請注意,所有 HTTP 標頭都可以被欺騙,但此標頭是為了保護客戶端。 不要使用這些值來保護您自己的數據。 如果您想了解更多信息,請閱讀有關 CORS 和 CSRF 的內容。

為什么更安全?

允許從其他位置訪問,然后您自己的受信任站點允許會話劫持。 我將舉一個小例子 - 圖片 Facebook 允許使用通配符來源 - 這意味着您可以在某處創建自己的網站,並使其向 facebook 發出 AJAX 調用(或打開 iframe)。 這意味着您可以獲取您網站訪問者的 Facebook 登錄信息。 更糟糕的是 - 您可以編寫POST請求並在某人的 Facebook 上發布數據 - 就在他們瀏覽您的網站時。

使用ACAO標頭時要非常小心!

警告,如果您遵循其他一些答案,Chrome(和其他瀏覽器)會抱怨設置了多個 ACAO 標頭。

錯誤將類似於XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access. XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

試試這個:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

我在調用 MVC3 控制器時解決了這個問題。 我補充說:

Response.AddHeader("Access-Control-Allow-Origin", "*"); 

在我之前

return Json(model, JsonRequestBehavior.AllowGet);

而且我的$.ajax抱怨它在我的 ajax 調用中不接受Content-type標頭,所以我將它注釋掉,因為我知道它的 JSON 被傳遞給 Action。

希望有幫助。

最好的是允許單個域名,請注意http://:

     header('Access-Control-Allow-Origin: http://www.foo.com', false);
     header('Access-Control-Allow-Origin: http://www.foo2.com', false));

使用*是一個非常糟糕的主意,這讓您對跨站點腳本持開放態度。 您基本上一直想要自己的域,范圍限定於您當前的 SSL 設置,以及可選的其他域。 您還希望它們都作為一個標頭發送。 以下內容將始終在與當前頁面相同的 SSL 范圍內授權您自己的域,並且還可以選擇包含任意數量的附加域。 它會將它們全部作為一個標頭發送,如果其他東西已經發送它們,則覆蓋前一個(s)以避免瀏覽器抱怨發送多個訪問控制標頭的任何機會。

class CorsAccessControl
{
    private $allowed = array();

    /**
     * Always adds your own domain with the current ssl settings.
     */
    public function __construct()
    {
        // Add your own domain, with respect to the current SSL settings.
        $this->allowed[] = 'http'
            . ( ( array_key_exists( 'HTTPS', $_SERVER )
                && $_SERVER['HTTPS'] 
                && strtolower( $_SERVER['HTTPS'] ) !== 'off' ) 
                    ? 's' 
                    : null )
            . '://' . $_SERVER['HTTP_HOST'];
    }

    /**
     * Optionally add additional domains. Each is only added one time.
     */
    public function add($domain)
    {
        if ( !in_array( $domain, $this->allowed )
        {
            $this->allowed[] = $domain;
        }
    /**
     * Send 'em all as one header so no browsers grumble about it.
     */
    public function send()
    {
        $domains = implode( ', ', $this->allowed );
        header( 'Access-Control-Allow-Origin: ' . $domains, true ); // We want to send them all as one shot, so replace should be true here.
    }
}

用法:

$cors = new CorsAccessControl();

// If you are only authorizing your own domain:
$cors->send();

// If you are authorizing multiple domains:
foreach ($domains as $domain)
{
    $cors->add($domain);
}
$cors->send();

你明白了。

您是否嘗試將 Access-Control-Allow-Origin 標頭實際添加到從您的服務器發送的響應中? 例如, Access-Control-Allow-Origin: *

暫無
暫無

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

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