首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单页应用与CSRF令牌

单页应用与CSRF令牌
EN

Stack Overflow用户
提问于 2018-05-03 16:29:16
回答 4查看 24.7K关注 0票数 14

我需要使用一个单一的页面应用程序(反应,Ember,角,我不在乎)与Rails CSRF保护机制。

我想知道是否需要在ApplicationController中创建这样的令牌:

代码语言:javascript
复制
class ApplicationController < ActionController::Base

  after_action :set_csrf_cookie

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

end

或我可以只创建一个令牌一次

每个会话还是根据(非获取)请求?

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

澄清

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

因此,在我的情况下,如果我为每个after_action创建一个新令牌,那么前面的CSRF令牌仍然适合该会话。那么,如何使前一个令牌失效呢?我不得不做?

因为只有我让它失效才有意义,对吧?

EN

回答 4

Stack Overflow用户

发布于 2018-05-08 03:10:52

客户端(SPA)

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

Rails似乎会在每个请求上生成一个新的CSRF令牌,但它将接受来自该会话的任何生成令牌。在现实中,它只是掩蔽一个单一的令牌使用一次垫每个请求,以防止SSL的破坏攻击。在https://stackoverflow.com/a/49783739/2016618上有更多的细节。您不需要跟踪/存储这些令牌。

服务器端

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

当然,您自己可以用不多的代码来复制它,但我不明白您为什么需要这样做。

你需要用API来保护CSRF吗?

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

票数 24
EN

Stack Overflow用户

发布于 2018-06-14 20:45:00

我就回答这个问题。详细信息在本文中解释:https://blog.eq8.eu/article/rails-api-authentication-with-spa-csrf-tokens.html

给定Rails正在为SPA设置cookie。

CSRF令牌在会话的生存期内有效。因此,是的,只要在登录后的会话期间生成一个CSRF令牌就可以了。

代码语言:javascript
复制
class LoginController < ApplicationController
  def create
    if user_password_match
      # ....
      cookie[:my_csrf_token]= form_authenticity_token
    end
  end
end

或者,您可以按照建议的方式刷新cookie。

代码语言:javascript
复制
class ApplicationController < ActionController::Base

  after_action :set_csrf_cookie

  def set_csrf_cookie
    cookies["my_csrf_token"] = form_authenticity_token
  end

end

SPA只需读取cookie并将其设置为标头即可。

两者都同样有效。

或者您只需提供CSRF令牌作为登录响应,SPA就会将其存储在某个地方,并在X-CSRF-Token头中使用它:

代码语言:javascript
复制
curl POST  https://api.my-app.com/login.json  -d "{"email":'equivalent@eq8.eu", "password":"Hello"}"  -H 'ContentType: application/json'
# Cookie with session_id was set

# response:

{  "login": "ok", "csrf": 'yyyyyyyyy" }

# next request 

 curl POST  https://api.my-app.com/transfer_my_money  -d "{"to_user_id:":"1234"}"  -H "ContentType: application/json" -H "X-CSRF-Token: yyyyyyyyy"

给定的Rails只接受标头身份验证。

如果您没有使用cookie发送session_id,那么您的API只使用Authentication头进行身份验证。那你就不需要CSRF保护了。

没有会话cookie,没有CSRF问题!

示例:

代码语言:javascript
复制
curl POST  https://api.my-app.com/login.json  -d "{"email":'equivalent@eq8.eu", "password":"Hello"}"  -H 'ContentType: application/json'
# No cookie/session is set

# response:
{ "login": "ok", "jwt": "xxxxxxxxxxx.xxxxxxxx.xxxxx" }

# Next Request:
curl POST  https://api.my-app.com/transfer_my_money  -d "{"to_user_id:":"1234"}"  -H "ContentType: application/json" -H "Authentication: Bearer xxxxxxxxxxx.xxxxxxxx.xxxxx"

再一次,这是只有当你不使用cookies来识别用户!所以在这种情况下CSRF不是一个问题,但您仍然可以防止跨站点脚本攻击,确保您的通信仅限于HTTPs,等等。

票数 2
EN

Stack Overflow用户

发布于 2018-05-07 10:27:40

我不知道你到底面临什么问题。但是,如果在New版本中遇到CSRF问题,并且需要在ajax请求中包含Rails CSRF令牌,则可以按照以下步骤执行。

最近我使用了Rails 5.1应用程序。

当使用ajax调用从API中获取一些数据时,我得到的是CSRF令牌问题:

代码语言:javascript
复制
‘WARNING: Can't verify CSRF token authenticity rails’

原因是

默认情况下,Rails 5.1删除了对jquery和jquery_ujs的支持,并添加了

代码语言:javascript
复制
//= require rails-ujs in application.js

它做了以下事情:

  1. 各种行动的武力确认对话;
  2. 从超链接中发出非获取请求;
  3. 使表单或超链接使用Ajax异步提交数据;
  4. 使提交按钮在表单提交上自动禁用,以防止双击。(出发地:https://github.com/rails/rails-ujs/tree/master)

但默认情况下,它不包括ajax请求的csrf令牌。小心点。我们必须明确地传递它,就像:

代码语言:javascript
复制
$( document ).ready(function() {
  $.ajaxSetup({
    headers: {
      'X-CSRF-Token': Rails.csrfToken()
    }
  });
  ----
  ----
});

请注意,在Rails 5.1版本中,您可以在js中获得“Rails”类,并且可以使用这些函数。

更新:--如果您使用的是Rails服务器端和其他前端,您真的不想使用Rails提供的CSRF令牌。因为您所使用的后端服务并不重要。

如果您的目标是阻止CSRF,则需要在后端设置CORS,即Rails后端。Rails现在在初始化器中提供了一个单独的文件。您可以提到哪些站点允许向后端发送ajax请求。

在这里编辑:

代码语言:javascript
复制
config/initializers/cors.rb

如果要进行身份验证,请使用basic auth、token auth或JWT。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50159847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档