Wednesday, August 8, 2018

How and why is Apache intercepting some CORS requests to Rails?

Leave a Comment

Before Chrome makes a cross-domain AJAX call it makes an OPTIONS check like this:

curl \ 'https://fubar.com/users/sign_in' \ -X OPTIONS \ -H 'Access-Control-Request-Method: POST' \ -H 'Origin: http://snafu.com' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36' \ -H 'Access-Control-Request-Headers: content-type' \ --compressed \ --insecure \ --verbose 

(I added --insecure and --verbose for testing.)

I can see this request in the Apache logs but it doesn't get to Rails.

127.0.0.1 - - [27/Jul/2018:09:22:44 -0400] "OPTIONS /users/sign_in HTTP/1.1" 200 - 

If I remove either the Access-Control-Request-Method or Origin headers then it does pass the request to Rails.

Something about the combination of these two headers seems to be causing Apache to handle the request itself and not give Rails a chance to process it.

I am not setting any headers or defining any rewrite rules in the Apache config; it's basically a vanilla install.

I'm not able to find any documentation or configurations explaining why this would be happening and how to prevent it.

1 Answers

Answers 1

1) OPTIONS HTTP call at 'https://fubar.com/users/sign_in' performed from chrome browser with request headers 'Access-Control-Request-Method: POST' and 'Origin: http://snafu.com'

2) the server at 'https://fubar.com/users/sign_in' receives the request

STEP 1

The routing is handles from either nginx or apache webserver which will first apply their own config rules. This settings are included in the file inside /etc/apache2 or /etc/nginx

For example with nginx you can define rules to add_header to the http response or settings to redirect to another url

for example

add_header "Access-Control-Allow-Origin: '*'" 

this will add the header "Access-Control-Allow-Origin: '*'" to all responses. If for example you apply this response to all OPTIONS requests, then all subsequent http request will be whitelisted from any http origin

STEP 2

once the nginx/apache redirection rules are applied, the rails router receives the request and redirects to your controller.

Here you can still add any header you want inside the controller, you can redirect OPTIONS request to a specific controller action, which can add a specific header, be careful to not add twice the same header as that can cause issues.

In this action you can rewrite the Access-Control-Allow-Origin header in the response from the OPTIONS request to whitelist only specific origin domains (you just need to write a routing rule which is applied only to OPTIONS requests)

The origin domain is written in the header of the request

request headers 'Access-Control-Request-Method: POST' and 'Origin: http://snafu.com'

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment