アクセス制御 - 許可 - 起源複数のオリジナルのドメイン?
-
11-09-2019 - |
質問
Access-Control-Allow-Origin
ヘッダを使用して複数のクロスドメインを可能にする方法はありますか?
私は*
の承知しているが、それは、あまりにも開いています。私は本当にただのカップルのドメインを許可したい。
例として、このような何かます:
Access-Control-Allow-Origin: http://domain1.example, http://domain2.example
私は上記のコードを試してみましたが、Firefoxで動作するようには思えません。
複数のドメインを指定するか、私はちょうど1で立ち往生していますし、それは可能ですか?
解決
は、それはあなたができるようにしたいあなたのサーバは、クライアントからの起源のヘッダーを読み取るドメインのリストにそれを比較することです行う際に推奨されるような音、それが一致した場合、バック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>
他のヒント
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");
}
これは私のために働いてます:
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
に入れた場合、、それは確かに動作します。
私は、複数のサブドメインにアクセスを持っていた、WOFF-フォントと同じ問題を抱えていました。
:私は私の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
で正規表現を変更することができます。
ここでは、nginxのとあなたのドメインと一致した場合は、フォント複数のサブドメインにサービスを提供する場合、これは便利ですバック起源ヘッダーをエコーする方法は次のとおりです。
location /fonts {
# this will echo back the origin header
if ($http_origin ~ "example.org$") {
add_header "Access-Control-Allow-Origin" $http_origin;
}
}
ここ
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
ヘッダの値として*
そのものを返す。
あなたが知っておくべき一つの欠点があります:とすぐとして、アウトソースファイルCDN(またはスクリプトを許可しない他のサーバ)には、またはあなたのファイルは、に基づいて応答を変更することは、プロキシにキャッシュされている場合「原点」要求ヘッダは動作しません。
複数のドメインについては、お使いの.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>
nginxのユーザーが複数のドメインのためのCORSを許可するために。彼のanwersが一つだけのドメインと一致したが、私はマーシャルの例@好きです。ドメインのリストと一致し、この正規表現をサブドメインには、それはフォントで動作するように容易に行います。
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";
}
}
これはドメインのみの与えられたリストと一致する「アクセス制御 - 許可 - 起源」のヘッダーをエコーされます。
URLリライト7.5+ IIS 2.0モジュールのを参照してくださいをインストールし、このSO に答える。
ここでのJava Webアプリケーションのためのソリューション、ベースyesthatguyからの回答です。
私はジャージーRESTの1.1を使用しています。
ジャージー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;
}
}
上記のように、Access-Control-Allow-Origin
はユニークでVary
である必要がありますが、CDN(コンテンツデリバリーネットワーク)の背後にある場合Origin
に設定する必要があります。
私の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';
}
たぶん私は間違っている、しかし、私の知る限りAccess-Control-Allow-Origin
を見ることができるようにパラメータとして"origin-list"
を持っています。
で定義する 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
そしてここから、私は別の起源が入院していると主張する必要がありますをスペースで区切られたの。
私は、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
。あなたののhttpd.confののファイルにこの内部<VirtualHost x.x.x.x:xx>
を追加します。あなたものの/ etc / apache2の/サイト利用可能/デフォルト-SSL のに行く必要がありますので、ごVirtualHost
ポートサフィックス(例えば:80
)を持っているならば、このディレクティブは、HTTPSには適用されないことに注意してくださいと<VirtualHost _default_:443>
部分の内側に、そのファイル内の同じディレクティブを追加します。
設定ファイルが更新されたら、ターミナルで次のコマンドを実行する必要があります:
a2enmod headers
sudo service apache2 reload
あなたがフォントに問題がある場合は、使用します:
<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
<IfModule mod_headers>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
あなたが使用することができます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();
});
HTTP_ORIGINは、すべてのブラウザで使用されていません。 どのように安全なHTTP_ORIGIN?の私にとっては、FFで空まで来ている。
私は、そのIDを持つレコードのための私のDBを確認し、SITE_URL列値(www.yoursite.com)を取得、私は自分のサイトへのアクセスを許可するサイトを持っているサイトのIDを介して送信します。
header('Access-Control-Allow-Origin: http://'.$row['SITE_URL']);
たとえリクエストがそのサイトのIDに関連付けられている私のDBに記載されているドメインからである必要が有効なサイトIDを介して送信ます。
ここでは、最新かつ計画フォントの定義の一部を含んで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>
とDjangoの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
は、.NETアプリケーションのための非常に簡単コピー/貼り付けのために、私は、Global.asaxファイル内からCORSを有効にするには、これを書きました。このコードは、応答への要求に与えられているものは何でも起源バック反映し、現在受け入れ答えで与えられたアドバイスを、次の。これは、それを効果的に使用せずに「*」実現しています。この理由は、それが「真」に設定「withCredentials」属性で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" , "*");
}
}
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を可能にします。
PHPコードの例
if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
$theMatch = $matches[0];
header('Access-Control-Allow-Origin: ' . $theMatch);
}
より柔軟なアプローチは、Apache 2.4の式を使用することです。あなたは、ドメイン、パス、ほぼすべての他のリクエスト変数に対して一致させることができます。応答はすべてのため*
ですが、その応答を受信する唯一のリクエスタは、とにかく要件を満たすものであります。
<IfModule mod_headers.c>
<If "%{HTTP:Host} =~ /\\bcdndomain\\.example$/i && %{HTTP:Origin} =~ /\\bmaindomain\\.example$/i">
Header set Access-Control-Allow-Origin "*"
</If>
</IfModule>
はSSL の上で広告を掲載し、上のGoogleのサポートの答えあなたはスペースURLを区切ることができることを示しているように思われるのRFC自体に文法。よくサポートされ、これが別のブラウザであるかどうかはわかりません。
、あなたが昔のイメージがまだ存在しているときのような問題に似、それが実際に動作するかどうか試してみ最初のキャッシュをクリアする必要があることを言及する価値があります(それはまだあなたのキャッシュに保存されているので)それがサーバー上で削除されます場合でも。
あなたのキャッシュを削除するには、Google Chromeでたとえば、 CTRL + SHIFT + DELの。
これは、多くの純粋な.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 ...
であると言うことに広がっていることに注意してください。これが今の私のようないくつかの時間のために同じ悩みを持つ人にお役に立てば幸いです。
答えの下には、C#に固有のものですが、コンセプトは、すべての異なるプラットフォームに適用可能であるべきである。
ウェブAPIからのクロスオリジンの要求を許可するように、あなたはあなたのアプリケーションにオプション要求を許可し、コントローラレベルでの注釈の下に追加する必要があります。
[EnableCors(UrlString、ヘッダー、メソッド)] 今起源は唯一の文字列を渡すことができます。あなたが渡したい場合はSO要求に複数のURLがカンマ区切り値として渡します。
UrlString =「ます。https://a.hello.com,https: //b.hello.com の "
のみ単一起源は、アクセス制御、許可原点ヘッダーに指定することができます。しかし、あなたはリクエストに応じてご対応して、原点を設定することができます。また変化ヘッダーを設定することを忘れないでください。 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
}
また、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");
}
答えは複数回のヘッダーを使用するように思われます。つまり、むしろ送信するよりも、
Access-Control-Allow-Origin: http://domain1.example, http://domain2.example, http://domain3.example
送信
Access-Control-Allow-Origin: http://domain1.example
Access-Control-Allow-Origin: http://domain2.example
Access-Control-Allow-Origin: http://domain3.example
Apacheの上で、あなたはhttpd.conf
と、この構文を使用して<VirtualHost>
の.htaccess
セクションまたはmod_headers
ファイルでこれを行うことができます:
Header add Access-Control-Allow-Origin "http://domain1.example"
Header add Access-Control-Allow-Origin "http://domain2.example"
Header add Access-Control-Allow-Origin "http://domain3.example"
トリックではなく最初の引数としてadd
よりappend
を使用することである。