[英]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
。 對於其他庫,它會是類似的。
如果您在 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
下指定特定主機,在這種情況下, *
和域列表都不起作用。
基本上跨站點請求偽造是當另一個域假設您的用戶已登錄並具有會話 cookie 向您的后端發出請求時。 因此它基於 cookie 並來自第三方域,因此無法訪問您瀏覽器中的任何內容。
XSS,跨站點腳本是指有人設法在您的頁面上運行腳本,從而在您的域上運行腳本。 這種攻擊可以訪問您瀏覽器中該域的任何內容。 這包括 sessionStorage 和 localStorage 以及瀏覽器可以讀取的普通 cookie。
CSRF 令牌存在於會話 cookie 中,並作為標頭與每個 API 請求一起發送,在保持后端無狀態的同時提供對 CORS 和 XSS 的保護。
任何后端服務所要做的就是:
exp
部分以避免 JWT 重放。完整的 JWT 在用作 cookie 之前使用服務器私鑰進行簽名,因此無法在沒有檢測的情況下進行操作。
因此,任何 CSRF 攻擊都會失敗,因為它只能間接訪問會話 cookie,並且無法從中讀取 CSRF 令牌,因此任何請求都會失敗。
任何 XSS 攻擊都會失敗,因為即使他們可以讀取 localStorage 中的 CSRF 令牌,也無法獲取會話 cookie。 做到這一點的唯一方法是從您的瀏覽器會話對后端運行請求,雖然這可能是可能的,但這些攻擊通常不是這樣工作的。 他們通常會嘗試導出會話信息,以便他們可以從另一台服務器發出請求,但這在這里不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.