17

I'm attempting to implement cross-domain HTTP access control without touching any code.

I've got my Apache(2) server returning the correct Access Control headers with this block:

Header set Access-Control-Allow-Origin "*"                   
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS" 

I now need to prevent Apache from executing my code when the browser sends a HTTP OPTIONS request (it's stored in the REQUEST_METHOD environment variable), returning 200 OK.

How can I configure Apache to respond "200 OK" when the request method is OPTIONS?

I've tried this mod_rewrite block, but the Access Control headers are lost.

RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L]       
Mark McDonald
  • 576
  • 1
  • 4
  • 12
  • 204 No Content is a more appropriate response which can avoid Apache reporting an internal error; see https://stackoverflow.com/questions/27703871/return-empty-response-from-apache/ – Adam Spiers Jun 01 '20 at 15:07

3 Answers3

14

You're adding a header to a non-success (non-2xx) response, such as a redirect, in which case only the table corresponding to always is used in the ultimate response.

Correct "Header set":

Header always set Access-Control-Allow-Origin "*"                   
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
alvosu
  • 8,357
  • 24
  • 22
9

If you set a directory for authenticated access, browsers such as Chrome and Safari (maybe others too) always send an uncredentialed OPTIONS request before the XmlHttpRequest call, which always gets 401 and fails if we don't set the .htaccess file/apache configuration to allow OPTIONS method without requiring authentication. That drove me nuts for 2 days and that's the kind of "esoteric" information that webmasters keep as secret, I guess! Anyway I configured my .htaccess like this and now it works:

AuthUserFile <path to password file>
AuthName "Thou shalt not pass!"
AuthType Basic
Options -Indexes
<LimitExcept OPTIONS>
  Require valid-user
</LimitExcept>

Then you have to set headers properly on the PHP scripts.

Mark McDonald
  • 576
  • 1
  • 4
  • 12
  • 1
    That last line is important. If the underlying web service can't handle the `OPTIONS` request, you will receive a 404 error. – user2297366 Jan 25 '18 at 01:55
  • THANK YOU! This was driving me nuts too. Even worse, the combination of this `R=200` rule with the redirect to an unauthorized path was somehow causing Apache to provide a useless "internal error" message rather than a more helpful 401. – Adam Spiers Jun 01 '20 at 14:45
8

Sometimes this approuch can help:

<IfModule mod_headers.c>
    Header add Access-Control-Allow-Origin "*"
    Header add Access-Control-Allow-Headers "origin, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
</IfModule>

RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ blank.html [QSA,L]

It is usefull when you have apache-like server