簡體   English   中英

如何從 Heroku 中托管的 Rails API 應用程序在瀏覽器中設置 cookie,該應用程序在 Netlify 中托管的 React 應用程序中運行前端?

[英]How can I set cookies in a browser from a Rails API app hosted in Heroku running the frontend in a React app hosted in Netlify?

我用 Rails --api --db:postgres標志構建了一個 API。 我使用 React create app在另一個應用程序中構建了前端。

  • Rails 6.1.4.1,Ruby 3.0.2p107
  • Rails 應用程序部署在 Heroku 中
  • Netlify 中的 React 應用程序
  • 我正在使用會話 cookie 來存儲用戶 ID,以及用於額外安全性的 CSRF 令牌(主要用於學習目的)

通過在端口localhost:3001 中運行 rails 服務器並在端口localhost:3000 中做出反應,這兩個 cookie 都在我的本地環境中按預期正確設置。

但是,在herokuapp.com 中部署Rails 並在netlify.app 中部署React 后,雖然瀏覽器在響應中收到cookie,但並沒有設置它們。

這是我在瀏覽器中看到的:

Cookie 響應

我的 Cors.rb 文件設置正確,以允許我的 netlify 域連接到服務器,就像my-domain.netlify.apphttps://my-domain.netlify.app 一樣

在設置 cookie 時,我嘗試了所有可以想象的設置組合,但似乎沒有任何效果。 目前它看起來像這樣:

def set_csrf_cookie
    cookies['CSRF-TOKEN'] = {
      value: form_authenticity_token,
      domain: my-app.herokuapp.com,
      same_site: :None,
      secure: true
    }
end

在我的 cors.rb 文件中,我在第一行有這個代碼:

Rails.application.config.action_controller.forgery_protection_origin_check = false

我的 application.rb 文件有這個配置:

config.api_only = true
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore

我的應用程序控制器看起來像這樣:

class ApplicationController < ActionController::API
  before_action :set_csrf_cookie

  include ActionController::Cookies
  include ActionController::RequestForgeryProtection

  protect_from_forgery with: :exception

  include Response
  include ExceptionHandler

  def cookie
    'ok'
  end

  private

  def set_csrf_cookie
    cookies['CSRF-TOKEN'] = {
      value: form_authenticity_token,
      domain: 'my-app.herokuapp.com',
      same_site: :None,
      secure: true
    }
  end
end

我通過從我的App.js組件進行 API 調用來設置 cookie。 該調用是對路徑 '/'進行的,該路徑被路由到application#cookie ,您可以在上面的應用程序控制器代碼中看到它。

我知道我能夠連接 API,因為一些不需要 CSRF 令牌的端點工作正常。

我有一種感覺,我的問題與托管在 2 個不同域中的應用程序有關。 我也認為這可能是一個前端問題,而不是一個后端問題。

任何成功完成此操作的人的幫助將不勝感激。

經過大量研究和大量測試,我發現我的 cookie 無法正常工作的主要原因是當今瀏覽器處理第三方 cookie 的方式。 事實證明,Safari 和 Chrome 在默認情況下會阻止它們。 我也錯過了跨站點 cookie 實際上並不存在的事實。

我寫了一篇文章解釋我如何解決這個問題: https : //medium.com/@ArturoAlvarezV/use-session-cookies-to-authenticate-a-user-with-a-rails-api-backend-hosted-in- heroku-on-one-domain-f702ddf8c07

基本上,我的解決方案非常簡單,從瀏覽器中刪除跨站點跟蹤保護,使用名為“rails_same_site_cookie”的 Ruby on Rails gem,並將此行添加到我的 production.rb 文件中:

config.action_dispatch.cookies_same_site_protection = :None

這對我有用。 默認情況下,這一行將 rails 中的所有 cookie 轉換為SameSite:NoneSecure:true ,包括 Rail 的內置會話 cookie。

我的開發人員工具不會在我的 cookie 面板中顯示 cookie,但現在每次我向 API 發出請求時,它們都會設置並隨我​​的憑據一起發送。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM