我在Docker容器中运行了一个Rails应用程序。我使用Devise
进行身份验证,使用Rack::Cors
进行CORS。
在我的机器上,一切都很好。部署完成后,我可以GET
正确登录页面,但当我填写登录表单并提交时,Chrome会回复一个空白页面和422(不可处理实体)状态代码。 Rails日志显示:
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
有趣的是,在Firefox上,一切都运行顺畅。
我已经尝试过关于Rails,CORS,CSRF的所有内容,但我无法找到解决方案。
我真的不知道这里有什么类型的信息,所以请随时在评论中询问详情,我会编辑问题。
答案 0 :(得分:0)
为了它的价值,我回顾了我的代码,找到了解决问题的方法。
我无法找到一个干净的解决方案,所以我通过禁用原点检查解决了这个问题:
# config/initializers/csrf_workaround.rb
Rails.application.config.action_controller.forgery_protection_origin_check = false
当然,这会引入安全漏洞,所以如果您有更清晰的方法来解决上述问题,请务必发布自己的答案。
答案 1 :(得分:0)
所以,我有一个类似的问题。只有我没有Devise或Docker。这是一个简单的形式。您的问题缺少很多上下文信息(如日志),因此我无法确定您是否遇到相同的问题,但这是我的解决方法。
我在提交简单表单时遇到InvalidAuthenticityToken
错误。令人困惑的是,它在Firefox上运行良好,但有时会在Chrome上随机失败,而在Android上的Chrome上始终会失败。
我查看了日志,发现了以下内容:
Started POST "/invitations" for 172.69.39.15 at 2019-09-26 22:34:26 +0000
Processing by InvitationsController#create as HTML
Parameters: {"authenticity_token"=>"F4ToAfkdPSnJsYewqvxXpsze3XitKHbiGnuEOR+628SdAY5jGRiG15GEuCSSoaVeVdO7eugAnsjKwmZPUpIepg==", "invitation"=>{"name"=>"[FILTERED]", "business"=>"[FILTERED]", "email"=>"[FILTERED]"}, "commit"=>"Apply for invite"}
HTTP Origin header (https://www.example.com) didn't match request.base_url (http://www.example.com)
Completed 422 Unprocessable Entity in 4ms (ActiveRecord: 0.0ms | Allocations: 226)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
引人注目的行是:
HTTP Origin header (https://www.example.com) didn't match request.base_url (http://www.example.com)
https://www.example.com
确实与http://www.example.com
不匹配,前者具有SSL。我正在通过Cloudflare路由我的应用程序,因此我使用SSL,但是我的应用程序期望使用request.base_url
但不使用SSL。
您需要强制您的应用使用SSL。这就是我为解决此问题所做的;您的确切步骤可能取决于您的体系结构。因为我使用的是Cloudflare,所以必须按此确切顺序执行这些步骤,否则,我的应用程序可能会被下线:
首先:我在服务器上配置了SSL。在这种情况下,我使用的是Heroku,它可以使用Let's Encrypt自动设置SSL。
第二:我通过将以下内容添加到production.rb
config.force_ssl = true
第三步::由于我不再需要服务器与Cloudflare之间的HTTP连接,因此将其从Flexible
切换到Full
。