Reputation: 395
I have a frontend React SPA interacting with a backend Rails API. In production, the frontend has a domain name mysecretsite.com
, while the backend is associated with mysecretsite.io
I am using ActionDispatch::Cookies to set access token in the browser, so that users can make subsequent requests with that token.
cookies.signed[:access_token] = { value: 'tmp_token_string', httponly: true, domain: :all }
It works as expected when React SPA and Rails API are both running locally in development on one computer.
After I had deployed React SPA and Rails API on different servers respectively, I noticed that cookies are not properly set in the browser.
I can reproduce such issue in development mode, where I placed React SPA on another computer within the same LAN.
I had tried configuring ActionDispatch::Cookies parameters like domain
with React SPA's IP:Port
string for development environment, or %w(.mysecretsite.com .mysecretsite.io)
for production environment, or just nil
, but it did not change anything.
What could be missed in my cookie settings?
controllers/application_controller.rb
class ApplicationController < ActionController::API
include ActionController::Cookies
end
config/application.rb
module RailsApp
class Application < Rails::Application
config.load_defaults 5.2
config.api_only = true
config.middleware.use ActionDispatch::Cookies
end
end
24 hours later, I have some additional information:
I took a look at the response header from Chrome browser.
In the React SPA running on the same computer with Rails API, access_token
cookie is properly set. And here is the response header:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://192.168.12.40:27511
Access-Control-Expose-Headers:
Access-Control-Max-Age: 1728000
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"ebd48cd3b0ac4fa7ba23a4d40b8508a2"
Vary: Origin
X-Request-Id: 9aa588f0-8569-b1ca-901945962e87
X-Runtime: 0.064807
While the React SPA running on another computer within the same LAN, access_token
cookie is not set, as what happened in production. And here is the response header:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://192.168.12.50:27511
Access-Control-Expose-Headers:
Access-Control-Max-Age: 1728000
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"ebd48cd3b0ac4fa7ba23a4d40b8508a2"
Vary: Origin
X-Request-Id: 9aa588f0-8569-b1ca-901945962e87
X-Runtime: 0.059074
In both cases, Set-Cookie
header is missing, but one of them successfully set the cookie, while the other failed.
Upvotes: 2
Views: 734
Reputation: 395
I figured out the issue myself. I just cannot assign .com
domain to React API, while associate .io
domain with Rails API.
The problem is that
You would need to have at least two levels of the domain to be the same in order to use cookies
as mentioned in Cookies across multiple TLDs?
In development environment, when React SPA and Rails API are running on different hosts, my workaround is assigning a common local domain name to two applications respectively.
Firstly, edit /etc/hosts
as something like:
192.168.12.40 mydevsite.com
192.168.12.10 api.mydevsite.com
Secondly in the Rails API app, add mydevsite.com:27511
as an additional origin to the file config/initializers/cors.rb
. And restart Rails API to take effect.
Lastly, update related request URLs in React SPA and the browser.
24 hours later
I can confirm that the issue has also been resolved in production environment, where Rails API is configured with a new domain name api.mysecretsite.com
However, I still have no idea why the official documentation has a setting example domain: %w(.example.com .example.org)
, and what kind of use cases they are presenting.
Upvotes: 3