我需要使用具有 Rails CSRF 保护机制的单页应用程序(React、Ember、Angular,我不在乎)。
我想知道我是否需要像这样在 ApplicationController
中创建一个 token :
class ApplicationController < ActionController::Base
after_action :set_csrf_cookie
def set_csrf_cookie
cookies["X-CSRF-Token"] = form_authenticity_token
end
end
或者我可以只创建一个 token 一次。
每个 session 还是每个(非 GET)请求?
我认为 token 在 session 有效之前仍然有效,对吧?
澄清:
我每次浏览页面时都会看到 Rails 默认应用程序(服务器呈现的页面)更新 csrf-token。所以每次它都会改变。
所以在我的情况下,如果我为每个 after_action
创建一个新 token ,那么之前的 CSRF-Token 仍然适用于该 session 。那么,如何让之前的token失效呢?我必须吗?
因为只有当我使它无效时才有意义,对吗?
最佳答案
客户端(SPA)
您只需每个 session 一次获取 CSRF token 。您可以在浏览器中保留它并在每次(非 GET)请求时发送它。
Rails 似乎会在每次请求时生成一个新的 CSRF token ,但它会接受从该 session 生成的任何 token 。实际上,它只是在每个请求中使用一次性一密来屏蔽单个 token ,以防止 SSL BREACH 攻击。更多详情,请访问 https://stackoverflow.com/a/49783739/2016618 .您不需要跟踪/存储这些 token 。
服务器端
我强烈建议使用 Rails 的 protect_from_forgery
指令,而不是自己在 header 中编码 CSRF token 。它将为每个请求生成不同的屏蔽 token 。
你当然可以用不多的代码自己重现这个,但我不明白你为什么需要这样做。
您需要使用 API 进行 CSRF 保护吗?
是的!如果您使用 cookie 进行身份验证,则需要 CSRF 保护。这是因为每次请求都会发送 cookie,因此恶意网站可以向您的网站发送 POST 请求并代表登录用户执行请求。 CSRF token 可以防止这种情况发生,因为恶意站点不知道 CSRF token 。
关于javascript - 单页应用程序和 CSRF token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50159847/