39

I want to configure apache for cross-domain access header. I have tried multiple combination as suggested on number of threads on the forum. But its not working for me.

The ways, I have tried:

1) Specify domain on different line as below with Header set :

Header set Access-Control-Allow-Origin "example1.com"
Header set Access-Control-Allow-Origin "example2.com"
Header set Access-Control-Allow-Origin: "example3.com"

With this setup its picking only last one and ignore rest of all.

2) Specify domain on different line as below with Header add :

Header add Access-Control-Allow-Origin "example1.com"
Header add Access-Control-Allow-Origin "example2.com"
Header add Access-Control-Allow-Origin: "example3.com"

With this its showing all three domains in header, but fonts are not getting picked up on Firefox.

3.) Tried Using SetEnvIf, but again its not working :

SetEnvIf Origin "http(s)?://(www\.)?(mydomain.com|mydomain2.com)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin

Finally working with "*", but I don't want to use this.

Please help with this.

regilero
  • 29,806
  • 6
  • 60
  • 99
Kuldeep
  • 507
  • 1
  • 5
  • 13
  • Did you read this one : http://stackoverflow.com/a/4730826/550618 for problems with 304 response code? – regilero Dec 19 '13 at 08:36
  • If I use "Header set", then its working on FF. But in that case Its taking only last domain :( and I want to configure for multiple domains. – Kuldeep Dec 19 '13 at 08:49
  • the problem is not `set` or `add`, it's to add the `always` keyword – regilero Dec 19 '13 at 09:26
  • Still having the same issue. If I use "always" keyword with set as below : Header always set Access-Control-Allow-Origin "example1.com" Header always set Access-Control-Allow-Origin "example2.com" Header always set Access-Control-Allow-Origin: "example3.com" Then its taking only last domain and fonts work on FF. On the other hand if I use always keyword with add as below : Header always add Access-Control-Allow-Origin "example1.com" Header always add Access-Control-Allow-Origin "example2.com" Header always add Access-Control-Allow-Origin: "example3.com" Then fonts doesn't work on FF. – Kuldeep Dec 19 '13 at 09:50
  • hi experts- Can you please guide me on this? – Kuldeep Dec 21 '13 at 08:19
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Web Applications Stack Exchange](http://webapps.stackexchange.com/), [Webmaster Stack Exchange](http://webmasters.stackexchange.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. – jww Feb 17 '18 at 13:56

9 Answers9

55

For 3 domains, in your .htaccess:

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

I've tried this and it works for me. Let me know if it doesn't for you.

George
  • 6,006
  • 6
  • 48
  • 68
  • 4
    This is the only way, it dynamically serve only one value by checking the host before serving. The "always append" or "add" didn't work for me. – Ciantic Apr 25 '14 at 16:47
  • 2
    Works great for me. I am wondering about "$0$1", as many other example just use "$0". It looks like it's robustness when re-using same .htaccess file for different web servers ($0 works for Apache). – Michael Biermann Feb 15 '15 at 22:06
  • Since the Response might differ depending on the "Origin" field, maybe the `Vary: Origin` header should be set as well (see http://stackoverflow.com/questions/25329405/why-isnt-vary-origin-response-set-on-a-cors-miss) – martin Jul 21 '16 at 14:28
  • 9
    It only worked for me when leaving the "$1" away. For some reason "$1" was set to "s" and therefore it did not match ("domain1.org" did not match "domain1.orgs"). – mcb Jul 28 '17 at 09:33
  • 7
    This is wrong. It needs to be `$0`, not `$0$1`. `$0$1` will append the matching group 1 to the URL. This is the matching group 1: `http(s)?` So it will append `s` for https origins and `undefined` for http origins. – rafaelgomesxyz Jan 05 '19 at 21:35
  • Agreed, using $0 is preferred. But the answer is freaking-awesome! Thanks, George! – Darek Apr 11 '19 at 17:54
  • On second thought, it might be beneficial to drop unwanted parts of the request Origin. One could use `(http(s)?://(myapp(api)?\-(dev|demo)\.azurewebsites\.net|localhost|localhost:4444)).*$`, which will accept multiple hosts/urls but place only the protocol and server in `$1`. – Darek Apr 11 '19 at 20:34
  • Can anyone explain to me what the 'e' means in the expression `%{AccessControlAllowOrigin}e` ? – Fabien Haddadi Aug 15 '19 at 11:38
  • Working great in 2020, just had to remove $1 to make it work, thanks for this solution – innovaciones Jun 13 '20 at 20:10
  • 1
    @FabienHaddadi %{AccessControlAllowOrigin}e is a type of format specifier for the header directive. https://httpd.apache.org/docs/current/mod/mod_headers.html#header – Yoshimitsu Jul 09 '20 at 21:42
18

Unless I'm misunderstanding the manual, it should be:

Header always append Access-Control-Allow-Origin: "example1.com"
Header always append Access-Control-Allow-Origin: "example2.com"
Header always append Access-Control-Allow-Origin: "example3.com"

The manual states that the set and add actions behave in the following way:

set: "The response header is set, replacing any previous header with this name"

add: "...This can result in two (or more) headers having the same name. This can lead to unforeseen consequences..."

Jon
  • 12,684
  • 4
  • 31
  • 44
4

To restrict access to certain URIs checkout these docs:

CrossOriginRequestSecurity

Server-Side Access Control#Apache_examples

One helpful trick is to use an Apache rewrite, environment variable, and headers to apply Access-Control-Allow-* to certain URIs. This is useful, for example, to constrain cross-origin requests to GET /api(.*).json requests without credentials:

RewriteRule ^/api(.*)\.json$ /api$1.json [CORS=True]
Header set Access-Control-Allow-Origin "*" env=CORS
Header set Access-Control-Allow-Methods "GET" env=CORS
Header set Access-Control-Allow-Credentials "false" env=CORS

Also, in general, according to W3 Wiki - CORS Enabled#For_Apache To expose the header, you can add the following line inside Directory, Location, and Files sections, or within an .htaccess file.

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "*"
</IfModule>

AND, you can use add rather than set, but be aware that add can add the header multiple times, so it's generally safer to use set.

Brad Sturtevant
  • 311
  • 3
  • 13
4

Try this one, it works for me. Apply in .htaccess:

SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.org|domain2\.com)$" origin_is=$0 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
MD IRFAN
  • 81
  • 2
1

Will be work 100%, Apply in .htaccess:

# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(domain1\.com|domain2\.org|domain3\.net)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-test-header, Origin, X-Requested-With, Content-Type, Accept"

# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
levin
  • 149
  • 1
  • 6
  • Both this and the approved answer adds a * at the end which isn't correct. I.E If I make a request from localhost:3000 the response header contains: `Access-Control-Allow-Origin: http://localhost:3000, *` – Yasin Yaqoobi Jun 20 '19 at 14:54
0

For Apache 2.4, I have used SET command for the Apache web server to set Header dynamically.

<IfModule mod_deflate.c>
  # CORS
  SetEnvIfNoCase Origin "http(s)?://(\w+\.)?(example.com|localhost)(:[0-9]+)?$" AccessControlAllowOrigin=$0
  Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
  Header set Access-Control-Allow-Credentials true
</IfModule>

ADD command didn't work for me.

Manjun Gim
  • 21
  • 5
0

I am using this in my .htaccess file for allowing access to multiple domains

 <ifModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(localhost:25120|domain.com|domain2.com)$" AccessControlAllowOrigin=$0
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
 </ifModule>    
Vicky Salunkhe
  • 9,869
  • 6
  • 42
  • 59
0

For Multiple domains, in your .htaccess:

 <IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain.com|domain.online|domain.in|domain.net|domain.site|domain.website|domain.space)$" AccessControlAllowOrigin=$0
    Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
</IfModule>

it 100% works for me

Sagar Mistry
  • 131
  • 11
-2

This works for me in Classic ASP:

If Request.ServerVariables("HTTP_ORIGIN") = "http://domain1.com" Then
  Response.AddHeader "Access-Control-Allow-Origin","http://domain1.com"
ElseIf Request.ServerVariables("HTTP_ORIGIN") = "http://domain2.com" Then
  Response.AddHeader "Access-Control-Allow-Origin","http://domain2.com"
'and so on
End If