我发现六年前,之前的开发人员注释掉了这行代码(Ruby,Rails):
#protect_from_forgery
我用默认值替换它:
protect_from_forgery with: :exception
当我在注销时尝试将项目添加到我的购物车时,我现在神秘地得到以下错误:
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.
我已经确定这是因为以下几行:
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
由于文档的原因,我了解导致预检请求的原因很高。但我不认为我正在做任何这些事情。
* 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
所以我最初的问题是如何确定触发预检请求的内容,然后我可以弄清楚如何防止它发生。这是我可以改变的情况,还是需要在id.foo-staging.com上更改某些内容(我无法访问,但可能会请求合适的人为我修复)。
我一整天都在谷歌搜索,似乎没有什么对我有任何意义,特别是因为我无法确切地说明错误。
我可以用这段代码解决问题:
skip_before_filter :open_id_authentication, :only => [:create], :if => :current_user and :anonymous_cart
但从安全的角度来看,我必须假设这是不安全的?
ETA:这是我在Network
标签上看到的这个请求:
一般:
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
请求标题:
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
查询字符串参数:
return_to: http://localhost.foo-staging.com:3000/cart/items
我认为问题是x-requested-with
请求标头。但我不知道如何解决这个问题。
EATA:
Many JavaScript frameworks such as JQuery will automatically send this header along with any AJAX requests. This header cannot be sent cross-domain:
我想我唯一的选择是弄清楚如何在没有AJAX的情况下重写它?
要避免预检请求,您必须删除x-requested-with标头,但是您遇到的错误是因为预检调用中的响应位置与Origin不同。要解决此问题,请更新代码以使用重定向报告的新URL,从而避免重定向。