单页应用程序和CSRF令牌

4 javascript session ruby-on-rails csrf reactjs

我需要使用带有Rails CSRF保护机制的单页应用程序(React,Ember,Angular,我不在乎)。

我想知道是否需要ApplicationController像这样创建令牌传送时间:

class ApplicationController < ActionController::Base

  after_action :set_csrf_cookie

  def set_csrf_cookie
    cookies["X-CSRF-Token"] = form_authenticity_token
  end

end
Run Code Online (Sandbox Code Playgroud)

或者我只能创建一次令牌

每个会话还是每个(非GET)请求?

我认为令牌在会话有效之前仍然有效,对吗?

澄清

每次浏览页面时,我看到Rails的默认应用程序(服务器呈现的页面)都会更新csrf令牌。因此,每次改变。

因此,在我的情况下,如果我为每个after_action会话创建一个新令牌,则以前的CSRF-Token对该会话仍然有用。那么,如何使先前的令牌无效?我必须?

因为只有当我使之无效时,对吗?

Sar*_*kom 11

客户端(SPA)

每个会话只需要获取一次 CSRF令牌。您可以在浏览器中保留它,并在每个(非GET)请求上发送它。

Rails似乎会在每个请求上生成一个新的CSRF令牌,但是它将接受该会话中生成的任何令牌。实际上,为了防止SSL BREACH攻击,它只是使用每个请求的一次性填充掩盖单个令牌。有关更多详细信息,参见/sf/answers/3484861761/。您无需跟踪/存储这些令牌。

服务器端

我强烈建议您使用Rails的protect_from_forgery指令,而不要自己在标头中编码CSRF令牌。它将为每个请求生成一个不同的掩码令牌。

您当然可以用很少的代码自己重现此代码,但是我不明白您为什么需要这样做。

您是否需要使用API​​进行CSRF保护?

是! 如果要通过cookie进行身份验证,则需要CSRF保护。这是因为Cookie随每个请求一起发送,因此恶意网站可能会将POST请求发送到您的站点,并代表登录用户执行请求。CSRF令牌可以阻止这种情况,因为恶意站点不会知道CSRF令牌。


Ant*_*hov -3

如果您使用 SPA 应用程序,那么您主要将 Rails 用作 API。CSRF 令牌是为服务器渲染而设计的……而不是 SPA。在 SPA 中,您已经在身份验证期间使用了令牌,因此无需为 CSRF 使用另一个令牌。CSRF 旨在保护跨站点调用,但 API 本身的设计方式是允许来自任何地方的请求,直到它们经过身份验证。

只需为您的 API 禁用它即可。我会使用一些API命名空间并设置 a BaseController,它将为所有 API 控制器继承。你应该在那里设置protect_from_forgery

class API::BaseController < ApplicationController
  protect_from_forgery with: :null_session
end
Run Code Online (Sandbox Code Playgroud)