Access-Control-Allow-Origin Multiple Origin Domains?


1049

Access-Control-Allow-Originヘッダーを使用して複数のクロスドメインを許可する方法はありますか?

は承知していますが、*オープンすぎます。私は本当にいくつかのドメインだけを許可したいです。

例として、次のようなもの:

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example

上記のコードを試しましたが、Firefoxでは動作しないようです。

複数のドメインを指定することは可能ですか、それとも1つだけで行き詰まりますか?



3
最新のFirefoxを使用した場合、カンマ区切りドメインもスペース区切りドメインも機能しませんでした。ドメインのリストと照合し、単一のホストをヘッダーに入れると、セキュリティがさらに向上し、正しく機能します。
ダニエルW.

1
HTTPSでこれに苦労している場合は、解決策を見つけました。
アレックスW

7
重要な注意Access-Control-Allow-Originヘッダーでクレタインドメインのみを許可して、他のドメインがこのエンドポイントのメソッド(REST APIメソッドなど)をトリガーできないことを意味するわけではありませ。これは、許可されていないオリジンがJavaScriptで結果を使用できないことを意味します(ブラウザがこれを保証します)。特定のドメインのエンドポイントへのアクセスを制限するには、許可されていないドメインに対してHTTP 401を返すなど、サーバー側のリクエストフィルターを使用します。
klues

1
Vary: Origin複数のURLを使用する場合は、常にヘッダーを追加する必要があります。次を
Null

回答:


861

推奨される方法のように聞こえるのは、サーバーにクライアントからOriginヘッダーを読み取らせ、それを許可するドメインのリストと比較し、一致する場合は、Originヘッダーの値をクライアントにエコーバックすることです。Access-Control-Allow-Origin応答のヘッダー。

では.htaccess、あなたはこのようにそれを行うことができます。

# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.example|dev02.otherdomain.example)$" AccessControlAllowOrigin=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header merge Vary Origin
    </IfModule>
</FilesMatch>

41
これは、W3Cが提案するものと一致します-w3.org/TR/cors/#access-control-allow-origin-response-hea
Simon B.

153
この回答に関する私の問題は、CDNを使用しているため、実際には役に立たないことであり、CDNがプログラムでヘッダーを設定する方法を制御できないことは明らかです。
BT、

6
-以下の私の答えでは実際の例(nginxの)stackoverflow.com/a/12414239/6084
mjallday

71
キャッシュまたはCDNが問題になる場合は、Varyヘッダーを使用して、異なるOriginリクエストヘッダー値に対して個別の応答を保持するようにキャッシュ/ CDNに指示します。「Vary:Origin」のようなヘッダーを応答に含めます。:キャッシュ/ CDNは、それはヘッダー「起源と要求に1つの応答を送信する必要があることを知っているfoo.example.comヘッダー」:起源と要求に、異なる応答「bar.example.com」。
Sean

10
@ saturdayplace、Originヘッダーにアクセスできる場合、CORSを過ぎています。
Paul Draper 14

222

PHPで使用している別のソリューション:

$http_origin = $_SERVER['HTTP_ORIGIN'];

if ($http_origin == "http://www.domain1.com" || $http_origin == "http://www.domain2.com" || $http_origin == "http://www.domain3.com")
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

12
stackoverflow.com/a/1850482/11635で提案されているアプローチを使用しないのはなぜですか[そしてワイルドカードを送信しないでください、要求されたオリジンのみです]?これは、これ以上何も達成することなく、より寛容ですか?
Ruben Bartelink

15
header('Access-Control-Allow-Origin: *')クレデンシャルフラグがtrueの場合、ワイルドカードを使用できないと時々言う- header('Access-Control-Allow-Credentials: true')おそらくそうなります。したがって、$http_origin条件が満たされている場合は、Allow-Origin 自体を使用することをお
勧めします

6
最後の行置き換えheader("Access-Control-Allow-Origin: " . $http_origin);、それを動作させるためには
フランソワ・ロメイン

2
このコードには欠陥があり、HTTP_ORIGINヘッダーが認識されない場合、Access-Control-Allow-Originはまったく設定されず、スクリプトは開いたままになります。
Stephen R

9
@StephenRの実際の「ワイドクローズ」は、他のドメインに対してスクリプトを開くことが目的であるため、より正確になります;)
Kaddath

113

これは私のために働きました:

SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is=$0 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

入れれ.htaccessば確実に動作します。


24
私にとって最良の解決策ですが、ポートのサポートを追加しました(例開発用のlocalhost:3000):SetEnvIf Origin "^ http(s)?://(。+ \。)?(localhost | stackoverflow.com | example1.com)( :[0-9] +)?$ "origin_is = $ 0
vszurma 2013年

2
stackoverflowに関するすべてのいくつかの回答のうち、これが機能したものです。
Meetai.com 2015

Header set Access-Control-Allow-Credentials trueこれを@Georgeの答えのように機能させるために追加する必要がありました
99の問題-構文は1つではありません

これは、Originを使用すると確実に機能します。ただし、場合によっては、Originは一部のリクエストで使用できず、ブラウザ固有でもあります。そこでのReferer代わりに使うことにしましたOrigin。使用してもReferer動作しますが、問題は、完全なURLを設定しAccess-Control-Allow-Originてドメイン名を切り取ってにReferer割り当てたいことAccess-Control-Allow-Originです。このecho http://example.com/index.php/ab/cd | cut -d'/' -f1,2,3-bashコマンドの結果のようなもの。(apache)confファイルで同じことを行うことは可能ですか?何か案が?
3AK、

1
これは私にはうまくいきません。2行を追加すると、常にコード500エラーが発生します。実際にPHP 5.6.15を使用
BoCyrill

91

woff-fontsにも同じ問題があり、複数のサブドメインにアクセスする必要がありました。サブドメインを許可するために、次のようなものをhttpd.confに追加しました。

SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
<FilesMatch "\.woff$">
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>

複数のドメインの場合、で正規表現を変更するだけで済みSetEnvIfます。


4
トリックをしました。正規表現を正しく調整してください。私は例えば、ドメイン自体を許可するように疑問符を追加するために必要な(.*\.?example\.org)ためexample.comsub.example.com
trkoch 2012

3
これをIIS 7に適応させる方法についての考えはありますか?
マーク・

しかし、それは目的を打ち破っていませんか?悪意のあるユーザーがOriginヘッダー値を偽造するのを防ぐにはどうすればよいですか?
グレゴリージョセフ2013

1
@GrégoryJosephAccess-Control-Allow-Originは、リソースを要求できるユーザーからリソースを隠すことではありません。これは、悪意のあるサイトがエンドユーザーにあなたのサイトを呼び出させないようにするためのものです。フォントファイルの場合、これはフォントのホットリンクを効果的に制限するだけです。なぜそれら(mozilla / firefox)が他のリソース(js、cssなど)に対して同じことを行わなかったのかは私を超えています。
Tracker1 2013

@trkoch、あなたの正規表現にバグがあります、それも可能にしsubexample.comます。:あなたはそれを変更する必要があります((.*\.)?example\.org)
bluesmoon

65

ドメインがNginxと一致する場合にOriginヘッダーをエコーバックする方法は次のとおりです。これは、フォントに複数のサブドメインを提供する場合に役立ちます。

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}

これはどのように違うのか理解できません:add_header Access-Control-Allow-Origin *; 説明してもいいですか?
Anoyz、2015

これは、指定されたドメインからのリクエストのみを送信することをブラウザに許可するヘッダーを返します。私が推測した場合、ブラウザはそのページにロードされた別のドメインからのコンテンツを認証して、そうでなければサーバーにアクセスできると思います。
mjallday 2015

7
@Anoyzの1つは、「Allow *」が許可されていないセキュリティが強化されている可能性がありますが、許可ヘッダーに指定された一致するホスト名は機能します。この例では、ドメイン間で認証情報を送信する場合、「Allow *」を使用できません
TCC

3
.これは正規表現なので、example.org のin は任意の値として解釈されますか?どの場合、これは誤ってカスタムexample-org TLDを許可しますか?
stuckj 2017年

1
正しい正規表現はする必要があります"^example\.org$"あなたは必ずハッカーが持つあなたの正規表現をすり抜けることができないようにする必要がありのでsubdomainexample.org(使用^)またはexample.orgevil(使用$)またはexamplezorg(エスケープ\.
ZEG

27

これは、AJAXからリクエストされているPHPアプリケーションに対して行ったことです

$request_headers        = apache_request_headers();
$http_origin            = $request_headers['Origin'];
$allowed_http_origins   = array(
                            "http://myDumbDomain.example"   ,
                            "http://anotherDumbDomain.example"  ,
                            "http://localhost"  ,
                          );
if (in_array($http_origin, $allowed_http_origins)){  
    @header("Access-Control-Allow-Origin: " . $http_origin);
}

要求元がサーバーで許可されて$http_originいる場合Access-Control-Allow-Origin*ワイルドカードを返す代わりに、ヘッダーの値としてそれ自体を返します。


20

注意が必要な欠点が1つあります。ファイルをCDN(またはスクリプトを許可しないその他のサーバー)にアウトソーシングするか、ファイルがプロキシにキャッシュされている場合は、「Origin」に基づいて応答を変更しますリクエストヘッダーは機能しません。


4
これについて詳しく説明してもらえますか、それとも私たちがもっと詳しい情報を探すことができる場所を教えてください。Limelightでそれを実現したいと思っています。あなたが間違っているといいのですが。私たちの技術担当者の1人は、CDNシードサーバーがヘッダーを送信する限り、CDN自体がヘッダーを送信すると述べました。まだテストしていない
BT

12
キャッシュまたはCDNが問題になる場合は、Varyヘッダーを使用して、異なるOriginリクエストヘッダー値に対して個別の応答を保持するようにキャッシュ/ CDNに指示します。「Vary:Origin」のようなヘッダーを応答に含めます。:キャッシュ/ CDNは、それはヘッダー「起源と要求に1つの応答を送信する必要があることを知っているfoo.example.comヘッダー」:起源と要求に、異なる応答「bar.example.com」。
Sean


20

複数のドメインの場合.htaccess

<IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain1.example|domain2.example)$" AccessControlAllowOrigin=$0$1
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
</IfModule>

4
このスニペットは私にとって完璧に機能します。しかし、私はそれが何をしているのか理解していません:D
Karl Adler

2
これは私にとってはうまくいきましたが、「^」を追加する必要がありました... SetEnvIf Origin "^ http(s)?://(www \。)?
gypsyDev

stackoverflow.com/a/14034228/209139とほとんど同じです。.htaccess構文は、PHPよりも読みにくいというだけのことです。Header set Vary Originこの答えへの良い追加になるでしょう。
TRiG 2015年

1
ご協力ありがとうございます
Cool Perfectionist

2
に変更する必要がありAccessControlAllowOrigin=$0$1ましたAccessControlAllowOrigin=$0。それ以外の場合は、HTTPSオリジンでは機能しませんでした。http://example.com正しく出てきましたhttps://example.comが、最後にhttps://example.coms追加でとして出sました。
TRiG 2016年

17

Nginxユーザーが複数のドメインでCORSを許可する場合。@marshallの例が好きですが、彼の回答は1つのドメインにのみ一致します。ドメインとサブドメインのリストを一致させるには、この正規表現を使用すると、フォントの操作が簡単になります。

location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
   if ( $http_origin ~* (https?://(.+\.)?(domain1|domain2|domain3)\.(?:me|co|com)$) ) {
      add_header "Access-Control-Allow-Origin" "$http_origin";
   }
}

これは、指定されたドメインのリストと一致する「Access-Control-Allow-Origin」ヘッダーのみをエコーし​​ます。


最後に\ zで正規表現をロックする必要があると考えてください。そうしないと、domain3.com.badhacker.comがアクセスを許可されてしまいます。
dft 2017年

@dftそれを行う最後に$を定義します
Adriano Rosa

申し訳ありませんが、要旨の例では、@ AdrianoRosaの実際の投稿は\ zと同じことを行います
dft


13

yesthatguyからの回答に基づいた、Java Webアプリのソリューションを次に示します。

Jersey REST 1.xを使用しています

Jersey RESTとCORSResponseFilterを認識するようにweb.xmlを設定します

 <!-- Jersey REST config -->
  <servlet>    
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param> 
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>com.your.package.CORSResponseFilter</param-value>
    </init-param>   
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.your.package</param-value>
    </init-param>        
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>

CORSResponseFilterのコードは次のとおりです

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;


public class CORSResponseFilter implements ContainerResponseFilter{

@Override
public ContainerResponse filter(ContainerRequest request,
        ContainerResponse response) {

    String[] allowDomain = {"http://localhost:9000","https://my.domain.example"};
    Set<String> allowedOrigins = new HashSet<String>(Arrays.asList (allowDomain));                  

    String originHeader = request.getHeaderValue("Origin");

    if(allowedOrigins.contains(originHeader)) {
        response.getHttpHeaders().add("Access-Control-Allow-Origin", originHeader);

        response.getHttpHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHttpHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }

    return response;
}

}

上記のリンクは期限切れです。新しい質問を追加するか、回答を詳細で更新してください。ありがとう
RajKumar Samala

詳細を追加しました。これがお役に立てば幸い
duvo

12

上記のように、Access-Control-Allow-Origin一意であるVary必要がありOrigin、CDN(コンテンツ配信ネットワーク)の背後にいる場合はに設定する必要があります。

私のNginx構成の関連部分:

if ($http_origin ~* (https?://.*\.mydomain.example(:[0-9]+)?)) {
  set $cors "true";
}
if ($cors = "true") {
  add_header 'Access-Control-Allow-Origin' "$http_origin";
  add_header 'X-Frame-Options' "ALLOW FROM $http_origin";
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Vary' 'Origin';
}

持っているset $cors隠された意味のいくつかの種類を、またはそれはあなたのconifgにだけ特有のでしょうか?2番目と一緒に省略できるようですif
mikezter

そうです、それがヘッダーを設定するためにテストする唯一の条件である場合、それは省略できます。私は私の設定に複数ありました。
hernvnc 2017年

9

多分私は間違っているかもしれませんが、私が見る限りでAccess-Control-Allow-Origin"origin-list"asパラメータがあります。

定義origin-listされます:

origin            = "origin" ":" 1*WSP [ "null" / origin-list ]
origin-list       = serialized-origin *( 1*WSP serialized-origin )
serialized-origin = scheme "://" host [ ":" port ]
                  ; <scheme>, <host>, <port> productions from RFC3986

そしてこれから、異なる起源が認められ、スペースで区切られるべきだと私は主張ます。


2
それは仕様の正しい解釈のようです。とはいえ、この仕様は現在のブラウザでは完全にはサポートされていないようです(たとえば、Firefox 17.0でテストしたところ、機能しないことが確認されました)。
リックRiensche

7
CORS指定5.1 Access-Control-Allow-Origin Response Header起源リストが制約されていることを状態:むしろ起源のスペース区切りのリストを可能にするよりも、それは単一起源または文字列「NULL」のいずれかです。
maxpolk 2013

2
私自身の回答のコメントで述べたように、これは実装者メモの一部であり、RFC 2119要件ではありません。「正しい」答えは、絶対にスペース区切りの値を使用することです。問題は、実装が不完全であり、「正しい」答えが必ずしも機能しないことです。すべきですが、そうではありません。ただし、将来的には実装が改善されるにつれて、これは変更される可能性があります。
Bob Aman

8

ExpressJSアプリケーションの場合、以下を使用できます。

app.use((req, res, next) => {
    const corsWhitelist = [
        'https://domain1.example',
        'https://domain2.example',
        'https://domain3.example'
    ];
    if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }

    next();
});

これにより、次の呼び出しによって他のすべての呼び出しが可能になります...
Ievgen Naida

@IevgenNaidaそれで?問題は何ですか?
eyecatchUp

7

私はこれをHTTPSを実行するドメインに設定するのに苦労したので、私は解決策を共有すると思いました。httpd.confファイルで次のディレクティブを使用しました。

    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

example.comドメイン名に変更します。この内部を追加し<VirtualHost x.x.x.x:xx>、あなたの中のhttpd.confファイル。あなたがあればということに注意してくださいVirtualHostポートサフィックス(例えばを持っている:80)あなたはまたに行く必要がありますので、このディレクティブは、HTTPSには適用されませんの/ etc / apache2の/サイト利用可能/デフォルト-SSLとそのファイル、内部で同じディレクティブを追加<VirtualHost _default_:443>セクション。

設定ファイルが更新されたら、ターミナルで次のコマンドを実行する必要があります。

a2enmod headers
sudo service apache2 reload

私はこのオプションが好きで、@ Georgeの実装と組み合わせたり修正したりしています。サーバーでa2enmodが利用できない場合があるため、メインのhttpd.confをチェックして、行:LoadModule headers_module modules / mod_headers.soがコメント化されていないかどうかを確認するだけです。
マイクコルメンディ2015

:私はそれを含めるように正規表現を変更して私の原点は、ポート番号を持っていた ^http(s)?://(.+\.)?example\.com(:\d+)?$
INDIV

5

フォントに問題がある場合は、以下を使用してください。

<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
    <IfModule mod_headers>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>

3

より柔軟なアプローチは、Apache 2.4の式を使用することです。ドメイン、パス、およびその他すべてのリクエスト変数と照合できます。送信される応答は常にですが、それを*受信する唯一の要求者はとにかく要件を満たすものです。式でOrigin(またはその他の)要求ヘッダーを使用すると、Apacheはそれを自動的にVary応答ヘッダーにマージするため、応答が別のオリジンで再利用されません。

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\\bcdndomain\\.example$/i && %{HTTP:Origin} =~ /\\bmaindomain\\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>

2
*ログインなどの資格情報を受け付けないブラウザがあるため、ここに来ました。したがって、の代わりに、一致するホスト名を渡す方が良いでしょう*
KeitelDOG

@KeitelDOG各ドメインのコードを繰り返すのではなく、複数の発信元がある場合、正しい発信元を動的にキャプチャして送信するにはどうすればよいですか?それはように見えかもしれない式を持つことはできますが、ドキュメントが私にクリアされていません。
Walf、

実際、私の本当の問題は、サーバーがこのオリジンを許可しているかどうかを確認するためにヘッダーをチェックするプリフライトリクエストAccess-Control-Allow-Originに対して、laravelがヘッダーを返さなかったためですOPTIONS。直した。だから*私にとっては本当の問題ではなかった。ただし、それでも一部のブラウザーは*資格情報を受け入れないため、WebアプリがCross-Originリクエストを送信するときに、ApacheまたはPHPのHTTP_ORIGIN変数Originを使用して動的にアクセスできるヘッダーを指定する必要があります。とにかく、あなたのソリューションはすべてのオリジンを許可するので良いですが、安全ではありません.htaccess$_SERVER['HTTP_ORIGIN'];
KeitelDOG

しかし、覚えておくべき2つのことは、1)提供する*ことですべてが可能になるということです。2)HOSTはORIGINとは異なります。HOSTは、リクエストヘッダーに渡される実際の「TARGET HOST」です。しかし、ORIGINはにINITIAL HOSTリクエストを送信するTARGET HOSTです。したがって、コードでORIGIN HOSTは無視され、使用されることはありません。上記の回答を見ると、ORIGIN値を使用してに追加する方法がわかりますAccess-Control-Allow-Origin
KeitelDOG

@KeitelDOG では、式で要求ヘッダー*を使用すると、OriginApacheがそれをVary応答ヘッダーに自動的にマージするため、誰も使用できませんreq_novary('Origin')(望ましくない可能性があります)。ブラウザーは、異なる応答が異なる可能性があることを認識してOriginおり、送信された値がテストに合格しない場合、Access-Control-Allow-Originヘッダーは設定されません。
ウォルフ

3

PHPコード:

$httpOrigin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;
if (in_array($httpOrigin, [
    'http://localhost:9000', // Co-worker dev-server
    'http://127.0.0.1:9001', // My dev-server
])) header("Access-Control-Allow-Origin: ${httpOrigin}");
header('Access-Control-Allow-Credentials: true');

2

HTTP_ORIGINはすべてのブラウザで使用されるわけではありません。 HTTP_ORIGINはどの程度安全ですか?私にとってそれはFFで空っぽになっています。
私は自分のサイトへのアクセスを許可するサイトにサイトIDを介して送信します。次に、そのIDを持つレコードをDBで確認し、SITE_URL列の値(www.yoursite.com)を取得します。

header('Access-Control-Allow-Origin: http://'.$row['SITE_URL']);

有効なサイトIDを介して送信した場合でも、リクエストは、そのサイトIDに関連付けられた私のDBにリストされているドメインからである必要があります。


2

以下は、Apacheの拡張オプションで、最新および計画中のフォント定義の一部が含まれています。

<FilesMatch "\.(ttf|otf|eot|woff|woff2|sfnt|svg)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "^http(s)?://(.+\.)?(domainname1|domainname2|domainname3)\.(?:com|net|org)$" AccessControlAllowOrigin=$0$1$2
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>
</FilesMatch>

2

ASMXサービスの複数ドメインアクセスを容易にするために、global.asaxファイルに次の関数を作成しました。

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string CORSServices = "/account.asmx|/account2.asmx";
    if (CORSServices.IndexOf(HttpContext.Current.Request.Url.AbsolutePath) > -1)
    {
        string allowedDomains = "http://xxx.yyy.example|http://aaa.bbb.example";

        if(allowedDomains.IndexOf(HttpContext.Current.Request.Headers["Origin"]) > -1)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Headers["Origin"]);

        if(HttpContext.Current.Request.HttpMethod == "OPTIONS")
            HttpContext.Current.Response.End();
    }
}

これにより、OPTIONS動詞のCORS処理も可能になります。


2

サブドメインを照合するためのPHPコードの例。

if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
        $theMatch = $matches[0];
        header('Access-Control-Allow-Origin: ' . $theMatch);
}

2

.NETアプリケーション用のかなり簡単なコピー/貼り付けのために、私はこれを書いて、CORSを global.asaxファイル。このコードは、現在受け入れられている回答で提供されているアドバイスに従い、リクエストで返されたオリジンが応答に反映されます。これにより、使用せずに「*」を効果的に実現できます。

これは、「withCredentials」属性を「true」に設定してAJAX XMLHttpRequestを送信する機能など、他の複数のCORS機能を有効にするためです

void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.HttpMethod == "OPTIONS")
    {
        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        Response.AddHeader("Access-Control-Max-Age", "1728000");
        Response.End();
    }
    else
    {
        Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (Request.Headers["Origin"] != null)
            Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]);
        else
            Response.AddHeader("Access-Control-Allow-Origin" , "*");
    }
}

1

そしてDjangoでもう1つ答えます。1つのビューで複数のドメインからのCORSを許可するには、次のコードを使用します。

def my_view(request):
    if 'HTTP_ORIGIN' in request.META.keys() and request.META['HTTP_ORIGIN'] in ['http://allowed-unsecure-domain.com', 'https://allowed-secure-domain.com', ...]:
        response = my_view_response() # Create your desired response data: JsonResponse, HttpResponse...
        # Then add CORS headers for access from delivery
        response["Access-Control-Allow-Origin"] = request.META['HTTP_ORIGIN']
        response["Access-Control-Allow-Methods"] = "GET" # "GET, POST, PUT, DELETE, OPTIONS, HEAD"
        response["Access-Control-Max-Age"] = "1000"  
        response["Access-Control-Allow-Headers"] = "*"  
        return response

1

AWS Lambda / APIゲートウェイ

サーバーレスAWS LambdaとAPI Gatewayで複数のオリジンを構成する方法については、非常にわかりやすいと思われるものに対してかなり大きなソリューションですが、ここを参照してください:

https://stackoverflow.com/a/41708323/1624933


現在、API Gatewayで複数のオリジンを構成することはできません。こちらを参照してください:https : //docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html)推奨事項(上記の答えは):

  • ブラウザから送信されたOriginヘッダーを検査する
  • 出所のホワイトリストと照合する
  • 一致する場合は、着信OriginをAccess-Control-Allow-Originヘッダーとして返します。それ以外の場合は、プレースホルダー(デフォルトのOrigin)を返します。

単純な解決策は、明らかにALL(*)を次のように有効にします。

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
        },
        body: JSON.stringify([{

しかし、API Gateway側でこれを行う方がよい場合があります(上記の2番目のリンクを参照)。


2
Access-Control-Allow-Credentials: trueワイルドカードを使用することはできませんAccess-Control-Allow-Origin: *<origin>代わりに特定のものを設定してください。
トム

@トム、うん、なぜそこにあったのかわからない、覚えてないけど、AWSに追加されたデフォルトからコピーしたのかもしれない。それを指摘してくれてありがとう。
timhc22

0

SSL介した広告配信に関するGoogleのサポート回答とRFC自体の文法は、URLをスペースで区切ることができることを示しているようです。これがさまざまなブラウザでどれだけサポートされているかはわかりません。


swl.org/TR/cors/#access-control-allow-origin-response-headerへの「sslを介した広告の配信」リンクには、「実際にはorigin-list-or-nullの生成はより制約されています。 。スペースで区切られたオリジンのリストを許可するのではなく、単一のオリジンまたは文字列「null」のどちらかです
spazm

その詳細に注意することは重要ですが、仕様に「実際に」と書かれている場合でも、その方法でのみ有効であることを意味するものではありません。つまり、そのようにすると、大部分の実装者が仕様を正しく実装しないか不完全に実装するため、問題が発生する可能性があります。仕様では、あなたは下のここEBNFで見ることができる、起源のスペースで区切られたリストも認めていませんorigin-listtools.ietf.org/html/rfc6454#section-7.1
ボブ・アマン

0

CORSを使用して機能させるために、私のような多くのコード例を試してみる場合、実際に機能するかどうかを確認するには、最初にキャッシュをクリアする必要があることを言及する価値があります。サーバー上で削除されます(まだキャッシュに保存されているため)。

例えば CTRL + SHIFT + DEL、Google Chromeでキャッシュを削除します。

これは、多くの純粋な.htaccessソリューションを試した後、このコードを使用するのに役立ち、これが唯一の機能であるように見えました(少なくとも私にとって):

    Header add Access-Control-Allow-Origin "http://google.com"
    Header add Access-Control-Allow-Headers "authorization, origin, user-token, x-requested-with, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

    <FilesMatch "\.(ttf|otf|eot|woff)$">
        <IfModule mod_headers.c>
            SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.com|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        </IfModule>
    </FilesMatch>

また、多くの解決策Header set ...ではタイプする必要があると言われていることは広く普及していますが、そうですHeader add ...。これが私のような数時間同じ問題を抱えている人を助けることを願っています。


0

以下の回答はC#に固有のものですが、この概念はすべての異なるプラットフォームに適用できるはずです。

Web APIからのクロスオリジンリクエストを許可するには、アプリケーションへのオプションリクエストを許可し、コントローラーレベルでアノテーションの下に追加する必要があります。

[EnableCors(UrlString、Header、Method)]原点は文字列としてのみ渡すことができるようになりました。SOリクエストで複数のURLを渡す場合は、カンマ区切り値として渡します。

UrlString = " https://a.hello.com,https://b.hello.com "


0

Access-Control-Allow-Originヘッダーに指定できる原点は1つだけです。ただし、リクエストに応じて、応答にオリジンを設定できます。また、Varyヘッダーを設定することを忘れないでください。PHPでは、次のようにします。

    /**
     * Enable CORS for the passed origins.
     * Adds the Access-Control-Allow-Origin header to the response with the origin that matched the one in the request.
     * @param array $origins
     * @return string|null returns the matched origin or null
     */
    function allowOrigins($origins)
    {
        $val = $_SERVER['HTTP_ORIGIN'] ?? null;
        if (in_array($val, $origins, true)) {
            header('Access-Control-Allow-Origin: '.$val);
            header('Vary: Origin');

            return $val;
        }

        return null;
    }

  if (allowOrigins(['http://localhost', 'https://localhost'])) {
      echo your response here, e.g. token
  }

-2

Asp.netアプリケーションのGlobal.asaxファイルでこれを設定することもできます。

protected void Application_BeginRequest(object sender, EventArgs e)
    {

    // enable CORS
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://www.youtube.com");

    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.