我想使用两种不同的protect_from_forgery策略构建一个rails应用程序:一个用于Web应用程序,另一个用于API。
在我的应用程序控制器中,我有这行代码:protect_from_forgery with: :exception
为了防止CSRF攻击,它运行正常。
在我的API命名空间中,我创建了一个从我的应用程序控制器继承的api_controller,它是API命名空间中所有其他控制器的父类,我更改了上面的代码:protect_from_forgery with: :null_session
。< / p>
可悲的是,我在尝试发出POST请求时遇到错误:“无法验证CSRF令牌的真实性”。
我不想跳过API控制器中的verify_authenticity_token方法,我只想在我的应用程序中有两个不同的策略,那么如何覆盖应用程序控制器中定义的protect_from_forgery策略呢?
编辑:好的,所以我最终做了我最初不想做的事情:改变我的api_controller的继承:它现在继承自ActionController :: Base,而不再是我的应用控制器。它现在确实有效,但是:
因此,如果有人有真正的方法来覆盖这种方法,我会很感激。
答案 0 :(得分:11)
如果您将protect_from_forgery with: :exception
留在应用程序控制器中,然后将以下内容放在API控制器中,该怎么办?
skip_before_action :protect_from_forgery
protect_from_forgery with: :null_session
这样,您仍然可以获得Web应用程序中所有控制器的标准CSRF攻击保护,但您也可以获得API方法的空会话行为。
答案 1 :(得分:3)
我正在运行一个类似结构的应用程序 - Web App + API。我解决了这样的CSRF问题:
代码:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, if: :isWebRequest?
def isWebRequest?
request.subdomains[-1] != 'api'
end
end
答案 2 :(得分:0)
迟到聚会,但是可以这样做:
class YourCustomStrategy
def initialize(controller)
end
def handle_request
end
end
在您的ApplicationController中或您想要的位置:
class ApplicationController < ActionController::Base
protect_from_forgery with: YourCustomStrategy
end