web-dev-qa-db-ja.com

Access-Control-Allow-Originを回避する方法

私は自分のサーバーへのajax呼び出しをこれらのajax呼び出しを防ぐように設定されたプラットフォーム上で行っています(ただし、サーバーのデータベースから取得したデータを表示するにはサーバーからデータを取得する必要があります)私のajaxスクリプトは動作しています、それはそれが処理できるように私のサーバーのphpスクリプトにデータを送ることができます。ただし、"Access-Control-Allow-Origin"によってブロックされているため、処理されたデータを元に戻すことはできません。

そのプラットフォームのソース/コアにアクセスできない。スクリプトを削除することはできませんので、削除することはできません。 (P/S私はGoogle Chromeのコンソールを使って、このエラーを見つけました)

以下に示す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が許されると思います。

誰かが私を助けてくれることを願っています。

184
ETAN

これをretrieve.phpの上に置きます。

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

これによりCORS保護が実質的に無効になり、ユーザーが攻撃にさらされることになります。alloriginsを許可する必要があることが完全に確信できない場合は、これをより具体的なOriginに限定する必要があります。

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

わかりました、でも、*はワイルドカードであり、すべてのドメインからのクロスサイトスクリプティングが可能であることをご存知ですか?

許可されているすべてのサイトに複数のAccess-Control-Allow-Originヘッダーを送信したいのですが、残念ながら公式には複数のAccess-Control-Allow-Originヘッダーを送信したり、複数の送信元を入れることはできません。

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ではワイルドカードのOriginを使用できます。つまり、自分のWebサイトをどこかに作成し、facebookにAJAX呼び出し(またはiframeを開く)させることができます。これはあなたがあなたのウェブサイトの訪問者のFacebookのログイン情報をつかむことができることを意味します。さらに悪いことに、あなたがPOSTリクエストをスクリプト化し、誰かのFacebookにデータを投稿することができます - それらがあなたのウェブサイトを閲覧している間だけです。

ACAOヘッダーを使用するときは非常に注意してください。

278
Rob Quist

警告、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.のようになります。

これを試して:

$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");
}
30
user3638471

MVC3コントローラを呼び出すときに私はこの問題を修正しました。追加した:

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

私の前に

return Json(model, JsonRequestBehavior.AllowGet);

また、私の$.ajaxは、私のajax呼び出しでContent-typeヘッダーを受け付けないと文句を言っていたので、JSONが渡されるのを知っているのでコメントアウトしました。アクションへ。

それが役立つことを願っています。

7
Atif Rehman

単一ドメインを許可するのが最善です、http://:に注意してください

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

サーバーから送信された応答に実際にAccess-Control-Allow-Originヘッダーを追加してみましたか? Access-Control-Allow-Origin: *のように?

2
Daniel Brockman

*を使用するのは本当に悪い考えです。これにより、クロスサイトスクリプティングを広く受け入れられるようになります。あなたは基本的にあなた自身の現在のSSL設定に範囲を定めたあなた自身のドメイン、そして任意で追加のドメインが欲しいです。また、それらすべてを1つのヘッダーとして送信したいとします。以下は常に現在のページと同じSSLスコープ内のあなた自身のドメインを認証し、オプションで追加のドメインをいくつでも含めることができます。ブラウザが複数のアクセス制御ヘッダーを送信することについて問題を起こす可能性を避けるために、それらをすべて1つのヘッダーとして送信し、他のものが既に送信している場合は前のヘッダーを上書きします。

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();

あなたはアイデアを得ます。

0
mopsyd