繁体   English   中英

Rails Set-Cookie on json API 响应

[英]Rails Set-Cookie on json API response

简单的基于令牌的 Rails 身份验证。
客户端服务器向 API 服务器发出请求。 API 服务器返回成功状态、json 编码的正文并理想地设置 cookie。

# response from API  
render json: {user: "user", token: "token_string"}, status: :created

此响应如何还设置 cookie?
我试图将, set_cookie: token附加到渲染语句。 我也
skip_before_filter :verify_authenticity_token, only: :create

最终目标是将令牌存储在浏览器 cookie 中。 我不想为令牌使用 HTML5 存储。

这是我的跨域 SPA/API 设置:

我在我的控制器中有这个,使用 Knock gem,动作:

class AccountTokenController < Knock::AuthTokenController
  def  create
    response.set_cookie(
      :jwt,
      {
        value: auth_token.token,
        expires: 30.minutes.from_now,
        path: '/api',
        secure: Rails.env.production?,
        httponly: Rails.env.production?
      }
    )

    render json: auth_token.payload, status: :created
  end
end

这将在客户端上设置一个 cookie,并在响应正文中返回所有令牌数据,包括一个 CSRF 令牌。

您还需要确保您的 AJAX 请求包含 cookie,默认情况下它们不包含。 使用 Axios,您可以通过设置选项withCredentials: true 对于其他库,它会是类似的。

CORS

如果您在 API 服务器上配置了 CORS,并且您应该这样做,那么您还需要一些额外的配置。 我为此使用了Rack::CORS gem,我的配置如下所示 (config/initializers/cors.rb):

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3001'
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      credentials: true
  end
end

请注意credentials: true的配置credentials: true以及需要在origins下指定特定主机,在这种情况下, *和域列表都不起作用。

CSRF 和 XSS

基本上跨站点请求伪造是当另一个域假设您的用户已登录并具有会话 cookie 向您的后端发出请求时。 因此它基于 cookie 并来自第三方域,因此无法访问您浏览器中的任何内容。

XSS,跨站点脚本是指有人设法在您的页面上运行脚本,从而在您的域上运行脚本。 这种攻击可以访问您浏览器中该域的任何内容。 这包括 sessionStorage 和 localStorage 以及浏览器可以读取的普通 cookie。

为什么这有效

CSRF 令牌存在于会话 cookie 中,并作为标头与每个 API 请求一起发送,在保持后端无状态的同时提供对 CORS 和 XSS 的保护。

任何后端服务所要做的就是:

  1. 验证 JWT 签名(以确保返回的不是伪造或操纵的会话 cookie)。
  2. 验证exp部分以避免 JWT 重放。
  3. 将标头 CSRF 令牌与 JWT 中的令牌进行比较。
  4. 验证 JWT 中的范围(这将特定于应用程序)。

完整的 JWT 在用作 cookie 之前使用服务器私钥进行签名,因此无法在没有检测的情况下进行操作。

因此,任何 CSRF 攻击都会失败,因为它只能间接访问会话 cookie,并且无法从中读取 CSRF 令牌,因此任何请求都会失败。

任何 XSS 攻击都会失败,因为即使他们可以读取 localStorage 中的 CSRF 令牌,也无法获取会话 cookie。 做到这一点的唯一方法是从您的浏览器会话对后端运行请求,虽然这可能是可能的,但这些攻击通常不是这样工作的。 他们通常会尝试导出会话信息,以便他们可以从另一台服务器发出请求,但这在这里不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM