【发布时间】:2021-07-11 17:44:50
【问题描述】:
我知道这已经在 SO 上提出a few times,但我无法取得进展。我在 Rails 5.0.7.2 上。
我每天被ActionController::InvalidCrossOriginRequest 抛出数百次。 Rollbar 说它主要是由 Bingbot 引起的,它在我的用户注册模式上,它来自 Devise。是一个GET请求,路径是/users/sign_up。
注意:这不是一个表单。它是一个简单询问用户的模式您想如何注册?电子邮件、Fb、Google 身份验证等。
基本上,我的网站上有一些 javascript 操作,例如 reddit 或 stackoverflow upvote 之类的图片。我不在这些链接上使用remote: true,而是我有一个$.ajax 调用来处理upvote,如下所示:
var token = document.querySelector('meta[name="csrf-token"]').content;
$.ajax({
// For the upvote, type will be POST
type: $this.data('method'),
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', token)
},
url: $this.data('url'),
success: function(data) {
// Some cleanup...
}
});
一旦登出的访问者尝试投票,它就会触发 ajax 请求,然后暂停(未授权)并重定向,如下所示:
Started POST "/upvotes/toggle_vote"
Processing by UpvotesController#toggle_vote as */*
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
Started GET "/users/sign_up"
Processing by RegistrationsController#new as */*
这是我覆盖的设计控制器:
class RegistrationsController < Devise::RegistrationsController
def new
# ... other code
respond_to do |format|
format.js { render layout: false }
format.html { respond_with self.resource }
end
end
end
在/views/devise/registrations 内部我有new.js.erb,它打开了“您想如何注册?”模态的。
我的尝试:
-
我不认为通过添加
protect_from_forgery except: :new来解决它是正确的答案(正如在类似问题中提出的那样),因为这本质上是不安全的。 -
我尝试按照this 重新排序
respond_to格式,但这会使注册模式无法打开。 -
我试图在
respond_to块中添加一个format.any { raise ActionController::RoutingError.new("Not Found") }catch-all,但这并没有解决错误。 -
正如您在上面的
$.ajax调用中看到的那样,我什至尝试设置X-CSRF-Token标头。
顺便说一下,完整的错误文本是这样的:
ActionController::InvalidCrossOriginRequest: Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript
有什么想法吗?
可能是因为UpvotesController#toggle_vote 重定向到RegistrationsController#new 并从 POST 更改为 GET,所以真实性令牌丢失了吗?
【问题讨论】:
-
这能回答你的问题吗? Rails InvalidCrossOriginRequest
-
不幸的是,它没有,因为我认为
protect_from_forgery应该是为了安全起见。该线程中没有其他建议的解决方案。另外,我没有混合 http/https 资源。 -
怎么样:
protect_from_forgery unless: -> { request.format.js? },仅用于您的一些 javascript 操作。 -
你能分享你的javascript动作代码吗(前端)?还有 - 你使用的是 jquery-rails 还是 rails-ujs?
-
@Joel_Blum 我正在使用 jquery-rails。我稍微整理了一下问题,您现在可以看到我的
$.ajax电话。
标签: javascript ruby-on-rails ruby ajax csrf