I discovered that six years ago, the previous developer commented out this line of code (Ruby, Rails):
#protect_from_forgery
I replaced it with the default:
protect_from_forgery with: :exception
and now I mysteriously get the following error when I try to add items to my cart while logged out:
Access to XMLHttpRequest at 'https://id.foo-staging.com/openid/checklogin?return_to=http%3A%2F%2Flocalhost.foo-staging.com%3A3000%2Fcart%2Fitems' (redirected from 'http://localhost.foo-staging.com:3000/cart/items') from origin 'http://localhost.foo-staging.com:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
I've pinned down that this is happening because of the following lines:
def get_user_identity_from_open_id_server
redirect_to "#{OPEN_ID_PROVIDER_URL}/openid/checklogin?return_to=#{Rack::Utils.escape(request.url)}"
end
def open_id_authentication
#stuff
get_user_identity_from_open_id_server
end
before_filter :open_id_authentication
I understand what causes a preflight request, at a very high level, thanks to the documentation. But I don't think I'm doing any of those things.
* the request method is anything other than GET, HEAD, or POST
* you’ve set custom request headers other than Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, or Width
* the Content-Type request header has a value other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
So my initial question is how do I determine what is triggering the preflight request, and then maybe I can figure out how to prevent it from happening. Is this a situation that I can change on my end, or does something need to change on id.foo-staging.com (which I don't have access to, but could probably ask the right person to fix it for me).
I've been Googling all day, and nothing seems to make any sense to me, especially because I can't pin down precisely what's wrong.
I can solve the issue with this code:
skip_before_filter :open_id_authentication, :only => [:create], :if => :current_user and :anonymous_cart
But I have to assume that this is unsafe, from a security standpoint?
ETA: This is what I see on the Network tab for this request:
General:
Request URL: https://id.foo-staging.com/openid/checklogin?return_to=http%3A%2F%2Flocalhost.foo-staging.com%3A3000%2Fcart%2Fitems
Referrer Policy: no-referrer-when-downgrade
Request Headers:
Provisional headers are shown
Access-Control-Request-Headers: x-requested-with
Access-Control-Request-Method: GET
Origin: http://localhost.foo-staging.com:3000
Referer: http://localhost.foo-staging.com:3000/p/Product0/1?id=1&slug=Product0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Query String Parameters:
return_to: http://localhost.foo-staging.com:3000/cart/items
I presume the problem is the x-requested-with request header. But I don't know how to resolve this.
EATA:
Many JavaScript frameworks such as JQuery will automatically send this header along with any AJAX requests. This header cannot be sent cross-domain:
I guess my only option is to figure out how to rewrite this without AJAX?
To avoid the preflight request you have to remove x-requested-with header but the error that you have is because the response location in the preflight call is different from the Origin. To fix the problem, update your code to use the new URL as reported by the redirect, thereby avoiding the redirect.