簡體   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