{"id":7686,"date":"2018-07-27T20:36:24","date_gmt":"2018-07-27T12:36:24","guid":{"rendered":"http:\/\/rmohan.com\/?p=7686"},"modified":"2018-07-27T20:36:24","modified_gmt":"2018-07-27T12:36:24","slug":"apache-configure-cors-headers-for-whitelist-domains","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=7686","title":{"rendered":"Apache Configure CORS Headers for Whitelist Domains"},"content":{"rendered":"<p>Apache Configure CORS Headers for Whitelist Domains<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>In the current implementation of Cross Origin Resource Sharing (CORS) the <code>Access-Control-Allow-Origin<\/code> header can only provide a single host domain or a wildcard as the accept value. This is not optimal when you have multiple clients connecting to the same virtual server and simply want to allow a list of known client host domains to the &#8220;allow&#8221; list.<\/p>\n<p>Since only a single domain in a single access header can be delivered back to the client, Apache must read the incoming <code>Origin<\/code> header and match it to the list of &#8220;white&#8221; (accepted) domains. If an appropriate match is found, echo the domain host back to client as the value of <code>Access-Control-Allow-Origin<\/code>.<\/p>\n<p>Use the following configuration snippet in the Apache virtual host &#8220;.conf&#8221; file or in the server &#8220;.htaccess&#8221; file. Ensure <code>mod_headers<\/code> and <code>SetEnvIfNoCase<\/code> are enabled.<\/p>\n<pre><code>&lt;IfModule mod_headers.c&gt;\r\n   SetEnvIfNoCase Origin \"https?:\/\/(www\\.)?(domain\\.com|staging\\.domain\\.com)(:\\d+)?$\" ACAO=$0\r\n   Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO\r\n&lt;\/IfModule&gt;\r\n<\/code><\/pre>\n<p>The regular expression <code>https?:\/\/(www\\.)?(domain\\.com|staging\\.domain\\.com)(:\\d+)?$<\/code> matches the URL of <code>Origin<\/code>, a required HTTP header for all requests. The pattern matches both the <code>http<\/code> and <code>https<\/code> protocols. It will match an optional <code>www.<\/code> subdomain and finally matches the actual host name of your whitelist entries. Any characters after the domain name are ignored. This example will therefore enable:<\/p>\n<pre><code>* <a class=\"vglnk\" href=\"http:\/\/domain.com\/\" rel=\"nofollow\">http:\/\/domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"https:\/\/domain.com\/\" rel=\"nofollow\">https:\/\/domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"http:\/\/www.domain.com\/\" rel=\"nofollow\">http:\/\/www.domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"https:\/\/www.domain.com\/\" rel=\"nofollow\">https:\/\/www.domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"http:\/\/staging.domain.com\/\" rel=\"nofollow\">http:\/\/staging.domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"https:\/\/staging.domain.com\/\" rel=\"nofollow\">https:\/\/staging.domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"http:\/\/www.staging.domain.com\/\" rel=\"nofollow\">http:\/\/www.staging.domain.com<\/a>\r\n* <a class=\"vglnk\" href=\"https:\/\/www.staging.domain.com\/\" rel=\"nofollow\">https:\/\/www.staging.domain.com<\/a>\r\n<\/code><\/pre>\n<p>If you send a request from <code><a class=\"vglnk\" href=\"http:\/\/staging.domain.com\/app\/\" rel=\"nofollow\">http:\/\/staging.domain.com\/app\/<\/a><\/code>, the response would include the header:<\/p>\n<pre><code>Access-Control-Allow-Origin: <a class=\"vglnk\" href=\"http:\/\/staging.domain.com\/\" rel=\"nofollow\">http:\/\/staging.domain.com<\/a>\r\n<\/code><\/pre>\n<p>If you sent another request from <code><a class=\"vglnk\" href=\"https:\/\/www.domain.com\/client\/\" rel=\"nofollow\">https:\/\/www.domain.com\/client\/<\/a><\/code>, the response would include the header:<\/p>\n<pre><code>Access-Control-Allow-Origin: <a class=\"vglnk\" href=\"https:\/\/www.domain.com\/\" rel=\"nofollow\">https:\/\/www.domain.com<\/a>\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Apache Configure CORS Headers for Whitelist Domains<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>In the current implementation of Cross Origin Resource Sharing (CORS) the Access-Control-Allow-Origin header can only provide a single host domain or a wildcard as the accept value. This is not optimal when you have multiple clients connecting to the same virtual server and simply want to [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7686"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7686"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7686\/revisions"}],"predecessor-version":[{"id":7687,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/7686\/revisions\/7687"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}