标签云

微信群

扫码加入我们

WeChat QR Code

Is there a way to allow multiple cross-domains using the Access-Control-Allow-Origin header?I'm aware of the *, but it is too open. I really want to allow just a couple domains.As an example, something like this:Access-Control-Allow-Origin: http://domain1.example, http://domain2.exampleI have tried the above code but it does not seem to work in Firefox.Is it possible to specify multiple domains or am I stuck with just one?


Rather than allowing a space-separated list of origins, (origin-list-or-null) is either a single origin or the string "null". (thanks maxpolk)

2019年05月23日32分31秒

Using the most recent Firefox, neither comma seperated, nor space seperated domains did work. Matching against a list of domains and putting a single host in the headers is still better security and does work properly.

2019年05月24日32分31秒

If you're struggling with this for HTTPS, I found a solution.

2019年05月24日32分31秒

sam or "*" ? shared based by returning the value of the Origin request header, "*", or "null"

2019年05月23日32分31秒

important note: allowing only cretain domains in the Access-Control-Allow-Origin header does not mean that other domains cannot trigger a method on this endpoint (e.g. REST API method). It just means that disallowed origins cannot use the result in javascript (browser ensures this). For restricting access to an endpoint for specific domains use a server-side request filter that e.g. returns HTTP 401 for disallowed domains.

2019年05月24日32分31秒

This matches what the W3C suggests -- w3.org/TR/cors/#access-control-allow-origin-response-hea

2019年05月24日32分31秒

My problem with this answer is it doesn't really help me, because we use a CDN, and obviously we can't control how the CDN sets headers programatically.

2019年05月24日32分31秒

Actual example (Nginx) in my answer below - stackoverflow.com/a/12414239/6084

2019年05月24日32分31秒

If caches or CDNs are a concern, use the Vary header to tell the cache/CDN to keep separate responses for different Origin request header values. You would include a header like "Vary: Origin" in your response. The cache/CDN then knows that it should send one response to a request with header "Origin: foo.example.com", and a different response to a request with header "Origin: bar.example.com".

2019年05月24日32分31秒

saturdayplace, if you have access to the Origin header, you are past CORS.

2019年05月24日32分31秒

Why not use the approach suggested in stackoverflow.com/a/1850482/11635 [and dont sent a wildcard, just the requested origin] ? This is just more permissive without achieving anything more?

2019年05月23日32分31秒

having header('Access-Control-Allow-Origin: *') sometimes says cannot use wild card if credentials flag is true - happens when header('Access-Control-Allow-Credentials: true')probably. So, better to Allow-Origin the $http_origin itself if the conditions are met

2019年05月23日32分31秒

replace the last line with header("Access-Control-Allow-Origin: " . $http_origin); to make it work

2019年05月23日32分31秒

This code appears flawed, in that if no HTTP_ORIGIN header is recognized, no Access-Control-Allow-Origin is set at all, leaving the script wide open.

2019年05月24日32分31秒

StephenR actually "wide closed" would be more accurate, as the purpose of this is to open the script to other domains ;)

2019年05月24日32分31秒

This is a great solution, thanks.

2019年05月24日32分31秒

Great answer, should be the accepted answer since it provides the solution as well!

2019年05月24日32分31秒

best solution for me, but i added port support (e.g. localhost:3000 for development): SetEnvIf Origin "^http(s)?://(.+\.)?(localhost|stackoverflow.com|example1.com)(:[0-9]+)?$" origin_is=$0

2019年05月24日32分31秒

It's working great!

2019年05月23日32分31秒

Of the several answers all around stackoverflow, this was the one that worked.

2019年05月24日32分31秒

Did the trick. Just make sure you adapt the regular expression correctly. I needed to add a question mark to allow the domain itself, e.g. (.*\.?example\.org) for example.com and sub.example.com.

2019年05月23日32分31秒

Any thoughts on how to adapt this for IIS 7?

2019年05月23日32分31秒

Isn't that defeating the purpose though ? What would prevent a malicious user from forging the Origin header value ?

2019年05月23日32分31秒

GrégoryJoseph Access-Control-Allow-Origin isn't about hiding resources from someone that can request it.It's about preventing a malicious site from having end users calling your site.In the case of font files, this can only effectively limit hot linking of fonts, why they (mozilla/firefox) didn't do the same for other resources (js, css, etc) is beyond me.

2019年05月23日32分31秒

trkoch, there's a bug in your regex, it will also allow subexample.com.You should change it to: ((.*\.)?example\.org)

2019年05月24日32分31秒

Can't understand how is this different from: add_header Access-Control-Allow-Origin *; Care to explain?

2019年05月23日32分31秒

this is going to return a header that authorizes the browser to only send requests from the domain specified. if i guessed i'd say the browser could authorize content from another domain loaded on that page to access the server otherwise.

2019年05月24日32分31秒

Anoyz for one thing there may be enhanced security where "Allow *" is not permitted, but a specified and matching host name for the allow header works. An example here, if you want to send authorization information cross domain, you can not use "Allow *"

2019年05月24日32分31秒

TCC, that is the exact reason -- I didn't want to limit the clients, but I did want to use authorization.The only way to do that according to the specs is to return the Origin.I'm actually surprised that they even have * -- either return the origin or don't.

2019年05月23日32分31秒

Is the . in example.org interpreted as any value since this is a regular expression? In which case, would this mistakenly allow a custom example-org TLD?

2019年05月24日32分31秒

Could you elaborate on this, or point us somewhere we can look for more info? I'm looking to do just that with Limelight, and I'm hoping you're wrong. One of our tech ops guys said that as long as our CDN seed server sends the header, the CDN itself will send it. Have yet to test it out

2019年05月23日32分31秒

If caches or CDNs are a concern, use the Vary header to tell the cache/CDN to keep separate responses for different Origin request header values. You would include a header like "Vary: Origin" in your response. The cache/CDN then knows that it should send one response to a request with header "Origin: foo.example.com", and a different response to a request with header "Origin: bar.example.com".

2019年05月24日32分31秒

Vary: Origin isn't supported by Akamai, one of the biggest CDN's out there... More details available here as well

2019年05月24日32分31秒

This snippet works perfectly for me. But I don't understand what it does :D

2019年05月24日32分31秒

this worked for me, although i had to add a '^' i.e.... SetEnvIf Origin "^http(s)?://(www\.)?

2019年05月24日32分31秒

It does pretty much the same as stackoverflow.com/a/14034228/209139. It's just that .htaccess syntax is a lot harder to read than PHP. Header set Vary Origin would be a nice addition to this answer.

2019年05月24日32分31秒

Thanks a lot for your help

2019年05月24日32分31秒

I had to change AccessControlAllowOrigin=$0$1 to AccessControlAllowOrigin=$0. Otherwise, it didn't work for HTTPS origins. http://example.com came out correctly, but https://example.com came out as https://example.coms, with an extra s on the end.

2019年05月24日32分31秒

gist.github.com/Stanback/7145487 was helpful for me.

2019年05月24日32分31秒

Think you need to lock that regex at the end with \z because otherwise domain3.com.badhacker.com would be allowed access.

2019年05月24日32分31秒

dft We define $ at the end which does that

2019年05月23日32分31秒

Sorry I meant in the gist example, the actual post by AdrianoRosa does the same thing as \z

2019年05月24日32分31秒

Worked like a charm, thank you!

2019年05月23日32分31秒

The Above Link is Expired, can you add new one, or update answer with more details, Thanks

2019年05月23日32分31秒

I've added more details,hope this helps

1970年01月01日00分03秒

has set $cors some kind of hidden meaning, or is it just specific to your conifg? it seems that it can be omitted together with the second if

2019年05月23日32分31秒

That's right, it can be omitted if that's the only condition you test to set the headers, I had multiple in my config.

2019年05月24日32分31秒

That does seem to be a correct interpretation of the spec; that said, the spec does not seem to be fully supported by current browsers (for example, I just tested this on Firefox 17.0 and confirmed that it will not work).

2019年05月24日32分31秒

The CORS specification section 5.1 Access-Control-Allow-Origin Response Header states that origin-list is constrained: Rather than allowing a space-separated list of origins, it is either a single origin or the string "null".

2019年05月23日32分31秒

As I mentioned in a comment on my own answer, that's part of a implementors note, not an RFC 2119 requirement. The 'correct' answer absolutely is to use space-delimited values. The problem is simply that the implementations are incomplete and so the 'correct' answer doesn't necessarily work. It should, but it doesn't. However, in the future, as implementations get better, this may change.

2019年05月23日32分31秒

I like this option and combined/modified it with the implementation thatGeorge has. Sometimes servers don't have a2enmod available, so all you have to do is check your main httpd.conf to see if the line: LoadModule headers_module modules/mod_headers.so is uncommented.

2019年05月23日32分31秒

My origin had a port number, so I modified the regular expression to include that:^http(s)?://(.+\.)?example\.com(:\d+)?$

2019年05月24日32分31秒

I came here because some browsers does not accept * with credentials like Login. So it will be better if you pass the matched hostname instead of *.

2019年05月24日32分31秒

KeitelDOG how does one dynamically capture the correct origin and send it back when there are multiple origins, instead of repeating the code for each domain? It looks like it might be possible with expressions but the docs aren't clear to me.

2019年05月24日32分31秒

In fact my real issue was because laravel didn't return the Access-Control-Allow-Origin header for OPTIONS preflight request that checks for headers to see if server allows this origin. I got it fixed. So * was not the real problem for me. But, still some browsers do not accept * with credentials, so when a Web App is sending Cross-Origin request, they HAVE TO specify HTTP_ORIGIN header that you might access dynamically with variable Origin in .htaccess for Apache, or $_SERVER['HTTP_ORIGIN']; in PHP. Anyway your solution is good to as it allows all origins, but less secure

2019年05月24日32分31秒

But 2 things to remember is that 1) Providing * allows everything. 2) HOST is different from ORIGIN. HOST is the actual 'TARGET HOST` that is passed to request header. But ORIGIN is the INITIAL HOST that send the request to the TARGET HOST. Therefore in your code, ORIGIN HOST is ignored and never used. See answers above and you will see how they use ORIGIN values to add them in Access-Control-Allow-Origin.

2019年05月23日32分31秒

KeitelDOG * Does not allow everyone because using the Origin request header in the expression causes Apache to automatically merge it into the Vary response header, unless one uses req_novary('Origin') (likely undesirable). Browsers know that they may get a different response for a different Origin and if the value sent doesn't pass one's test, the Access-Control-Allow-Origin header is never set.

2019年05月24日32分31秒

'serving ads over ssl' links to the spec w3.org/TR/cors/#access-control-allow-origin-response-header which adds a note, "In practice the origin-list-or-null production is more constrained. Rather than allowing a space-separated list of origins, it is either a single origin or the string "null".

1970年01月01日00分09秒

While it's important to note that detail, when a specification says "In practice", it doesn't mean that it's only valid to do it that way. It means that if you do it that way, you may run into problems because the majority of implementors either implement the spec incorrectly or incompletely. The specification does allow for a space-separated list of origins, which you can see here in the EBNF under origin-list: tools.ietf.org/html/rfc6454#section-7.1

2019年05月23日32分31秒

there's a variation on this which seems to work: stackoverflow.com/questions/9466496/…

2019年05月24日32分31秒

Just spent two hours trying to fix an issue related to CORS and it turns out that it was because of multiple Access-Control-Allow-Origin headers. I removed the multiple Access-Control-Allow-Origin headers and it started working. So this is not the right answer despite the number of votes. Use this method instead to support multiple domains: stackoverflow.com/a/1850482/123545

2019年05月24日32分31秒

This is not a correct answer.

2019年05月24日32分31秒

The specs clearly say that multiple values will cause the CORS algorithm to fails. So this isn't correct.

2019年05月23日32分31秒

Also confirming this is incorrect. Using this to serve CSS to four domains, I receive an error in Chrome's log "[...] header contains multiple values 'aaa.com, bbb.com', but only one is allowed". It does not matter if you define it as one header, or multiple, or using add vs. set. It just doesn't work.

2019年05月24日32分31秒