Setting HTTP-only cookies for session based auth (React SPA + Python backend)

I set up Session Middleware with my FastAPI backend to authenticate my React frontend users, which worked with domain=127.0.0.1. Now that I’ve deployed both my frontend and my backend to two separate servers using Fly.io, the session cookies are no longer being accepted.

My frontend is deployed at playlist-mood-evaluator-ui.fly.dev, and my backend is deployed at playlist-mood-evaluator-api.fly.dev.

I have added screenshots and code snippets in this Stackoverflow post.

Basically I’m wondering if I should set the domain to something else instead? or if this is the correct strategy and I’m just missing something?

Please read that to understand the domain property.

I have read that a dozen times, and that is what I have provided the domain of my UI, playlist-mood-evaluator-ui.fly.dev, as the server to receive the cookie from my backend.

You can see all of this in the screenshots.

Do you have any insight into why this domain is considered invalid? That would be helpful. Thanks!

You’ve read it a dozen times but I’m not sure you understand. When you set the Domain=example.com, then the cookie will only get sent to that domain.

When you set yours to Domain=playlist-mood-evaluator-ui.fly.dev, guess where that cookie gets sent? Will playlist-mood-evaluator-api.fly.dev ever see that cookie? Open 2 tabs: 1 for your ui and the other for your api. Open network settings and look at the Application tab. Under Storage > Cookie > your domain.

I found the issue here, to your point:

Does this mean I simply cannot store cookies on cross-domain requests (xxx-ui.fly.dev cannot save a cookie from xxx-api.fly.dev?) I feel like every thing I read on the subject conflicts with the last thing I read. My apologies for doubting the docs you sent.

So my session-based auth strategy is impossible given my circumstances? If so, is there a way to configure my API and my UI to be subdomains of some playlist-mood-evaluator.fly.dev domain? Something like api.playlist-mood-evaluator.fly.dev and ui.playlist-mood-evaluator.fly.dev?

I don’t think you can do sub-subdomains on fly.dev. Normally you have your own mydomain.com domain where api.mydomain.com is the api and mydomain.com is your ui. Then you set your Domain=.mydomain.com (the leading “.” is important)

Yes I recognize that pattern as well, but that’s not possible on Fly since I’d need the api. prefix?

Can you not buy your own domain?

You mean purchase playlist-mood-evaluator.com? I absolutely am willing to do that. How does that solve my problem at hand, though? If I want to deploy my apps through Fly, I’d still have to buy two separate domains for my API/UI, and register them both as independent projects following these docs for each, no?

No, that would solve your problem. You create DNS records to route api.playlist-mood-evaluator.com to your fly api machine and playlist-mood-evaulator.com to your fly ui machine.
You only need a single domain and can have as many subdomains as you want.

Okay I have purchased the domain (and subdomains) through name-cheap, but then registered the domain through Cloudfare and to take advantage of their free TSL cert offerings.

I am struggling to keep track of all of these different certs and access ‘layers’… Here is the explanation of my configuration:

  1. Domain purchased through namecheap
  2. Registered domain through Cloudfare, copied DNS records like so:
  3. Updated domain nameservers on namecheap to use Cloudfare’s nameservers instead
  4. NOW I WANT TO CONFIGURE HTTPS! I need to setup an TSL cert. Namecheap didn’t give me one for free, which is why I’m using Cloudfare!
  5. I have created an Origin CA certificate on Cloudfare, following these instructions: Origin CA certificates | Cloudflare SSL/TLS docs
  6. Now I want to install this origin CA certificate on my ‘origin server’. This is here on Flyio, correct? If I understand correctly, I need to install this origin CA cert on my UI server specifically.
  7. I created + copied the .pem and .key files generated in step (6) for my Origin CA cert over to my UI repository.
  8. Following these nginx instructions, I am now trying to install these certs through nginx, like so:
    In my dockerfile, I copy the certs to the etc/ssl/ folder of my docker image:
    COPY ./.cert/server.key ./.cert/server.pem /etc/ssl/

Then in my nginx.conf file, I add the listening ports for https and specify the location of the cert files:

server {
    listen 80;
    listen 443 default_server ssl;
    ssl_certificate    /etc/ssl/server.pem;
    ssl_certificate_key    /etc/ssl/server.key;
    
    # (other stuff)
    server_name  localhost;

    root   /usr/share/nginx/html;
    index  index.html index.htm;
    include /etc/nginx/mime.types;

    gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    location / {
      try_files $uri $uri/ /index.html;
    }
  }

This is now configured for both HTTP and HTTPS, as explained in these nginx docs.

Is this the correct procedure for installing a TLS cert? I thought I was doing everything right until I ran into the Fly.io docs:

Can you just help me reconcile these two sets of instructions, and determine which steps I’m missing or doing incorrectly?

I really appreciate all your time. I’m so close to being done with my first side project and I just need the extra support, clearly!

You do not/should not set up ssl in your nginx since fly terminates TLS.
And you don’t really need nginx here. What’s your reasoning for adding it?

When I tried to access my new domain playlistmoodevaluator.com, Firefox didn’t load the page because it said HTTPS wasn’t enabled. Are you saying I don’t need to terminate TLS from the Cloudfare side because it’s simply routing traffic to my Fly servers, which handles TLS on its own?

So if I simply remove my Origin CA cert from Cloudfare but force https for my domain, I won’t get the HTTPS error I got initially? Can you explain this further?

RE: your second question, This is me building off of the CRA-Fly Github template. I built this using CRA, which until you informed me is no longer supported, I thought this was considered pretty standard practice. I am nervous and hesitant to migrate to something like Vite when I already have a working app! I just need to deploy it, and this Github repo offered a way for me to do so.

If you genuinely think it would be easier + faster to migrate my CRA app to Vite, I will try it.

Just please give me some thorough instructions for:

  1. Terminating TLS (remove Cloudfare certs? what should my nginx.conf look like, assuming I keep it?)
  2. Migrate to Vite, redeploy app? (Still need to know what to do for #1)

Thank you for your help, I have redeployed my frontend and everything is working as expected.

Now I am trying to query backend application (hostname: https://playlist-mood-evaluator-api.fly.dev) that is registered through Cloudfare’s DNS at api.playlistmoodevaluator.com, a subdomain of my playlistmoodevaluator.com domain. I have configured everything as we have discussed!

The problem: my frontend is seemingly unable to reach my backend at api.playlistmoodevaluator.com. I’ve attached a screenshot of the failed request:

The error in the console is as follows: (Reason: CORS request did not succeed). Status code: (null).

There is also the missing HTTPS symbol, indicating that my backend is not encrypted with TLS? Do I just need to add a cert to my backend application, which is expecting HTTPS?

My app is accessible from its original Fly URL, but the browser tells me the subdomain that I registered at Cloudfare is not HTTPS. Is this an error in my configuration for Cloudfare and my subdomain, or the config for my backend app deployed on Fly io that my subdomain routes to?

EDIT:

Added the certificate via Fly dashboard, registered to my subdomain. Everything works as intended. I should have just trusted my gut instinct instead of asking first!

Thanks for your help along the way.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.