Cookies are not set in browser in SPA to API communication

Viewed 1742

I am setting up React SPA (www.mysite.com) and Rails API (api.mysite.com) app. When I use same URL name everything works as expected, however when URL names are different, the web browser is not setting site cookie. With cookies missing, CSRF validation also fails of course. So for example if SPA App runs on localhost and Rails API App on localhost:3000 all good, the problem is only when I use the intended DNS names.

Sounds like a CORS problem but I can’t find where for many days now…

Here is my config:

Rails side I am using rack-cors ruby gem

config/initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
   allow do
     origins 'localhost’,  'www.mysite.com',

     resource '*',
       headers: :any,
       credentials: true,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
   end
end

Rails.application.config.action_controller.forgery_protection_origin_check = false

on React side I have axios config as follows:

src/App.js

axios.defaults.xsrfCookieName = "CSRF-TOKEN";
axios.defaults.xsrfHeaderName = "X-CSRF-Token";
axios.defaults.withCredentials = true;

When React App starts, it makes a GET request to the API backend to grab CSRF token for later use. In the same time browser is supposed to set site cookies.

    axios
        .get("/sessions/csrf_token", {
          headers: { "Content-Type": "application/json"
          },
        })
        .then(response => {
          // do stuff
          });
        });

The response headers look the same in both cases when site cookies are set and missing

enter image description here

I can also see cookies are sent to the browser and yet they are missing under Cookies section

enter image description here

Any thoughts on what I can be missing here are very much appreciated!!! Thanks!!

UPDATE:

I also should have mentioned that my session config file is set to allow subdomains

config/initializers/session_store.rb

Rails.application.config.session_store :cookie_store, key: '_mysite_session', expire_after: 8.hours, domain: :all, tld_length: 2

Possibly something else is wrong with my cookies config, but I can't figure out where to look at and what other settings should be checked.

Here is a screenshot of my Cookies pane when I use localhost and cookies are retained in the browser as expected:

enter image description here

When I use www.mysite.com and api.mysite.com names, the pane on the right is just empty.

2 Answers

I've been looking into this and I think this may be relevant to what you're seeing:

Share cookie between subdomain and domain

Apparently if you don't specify a domain in the set-cookie header, the cookie is considered "host only". So you might have to have it look like:

Set-Cookie: name=value; domain=mydomain.com

I'm sure this is doable with Axios.

I had the same problem. I fixed this, setting a domain for cookies.

In ApplicationController, when you set CSRF-TOKEN do the follows

cookies["CSRF-TOKEN"] = {
  value: form_authenticity_token,
  domain: ".mysite.com"
}

And in config/application.rb add the domain too config.middleware.use ActionDispatch::Session::CookieStore, domain: ".mysite.com"

I hope that this answer helps you

Related