オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS)において、Rails APIとフロントのfetch API間でCookieを送受信できるようにする方法について紹介します。
rack-corsの設定
rack-corsはRailsアプリケーションのCORS設定用のgemです。
CORSでCookieを送信する場合はcredentials: trueを追加します。
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
unless Rails.env.production?
allow do
### 『localhost』『localhost:[ポート番号]』『[サブドメイン].local.example-dev.com』のオリジンを許可
origins(['localhost', /localhost:\d+\Z/, /(.+).local.example-dev.com\Z/])
resource '*',
headers: :any,
- methods: [:get, :post, :put, :patch, :delete, :options, :head]
+ methods: [:get, :post, :put, :patch, :delete, :options, :head],
+ credentials: true
end
end
end
上記の設定により、レスポンスヘッダのSet-CookieにCookieがセットされます。
credentials: trueがないとSet-CookieにCookieがセットされないため、フロント(ブラウザ)はCookieの取得ができません。
fetch APIの設定
fetch APIでCookieを取得する場合はcredentials: 'include'を追加します。
### APIのドメインが『api.local.example-dev.com』の場合
- fetch("http://api.local.example-dev.com/[エンドポイント名]")
+ fetch("http://api.local.example-dev.com/[エンドポイント名]", { credentials: 'include' })
Rails API側のCORS設定でcredentials: trueをしていてもfetch APIでcredentials: 'include'を追加しなければ、Set-CookieにセットされたCookieをブラウザにセットできません。
逆に、fetch APIでcredentials: 'include'を設定しているのにRails API側のCORS設定でcredentials: trueをしていない場合はAccess to fetch at 'http://[APIのエンドポイント]' from origin 'http://[フロントのエンドポイント]' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.というエラーがブラウザに発生します。
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!



