Hiro Shaw
Hiro Shaw

Reputation: 395

ActionDispatch::Cookies are not set across domains

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

Answers (1)

Hiro Shaw
Hiro Shaw

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

Related Questions