I have deployed my sveltekit frontend and python flask backend on vercel. On localhost, they worked just fine however when I deployed it, the cookies were not persistent.
When I login, the cookies are there, however, when I refresh my page the cookie gets deleted. I have set Max-age to 3 days, yet it is disappearing on refresh. I just couldn't understand that.
My frontend domain was: time-master-frontend.vercel.app
My Backend domain was: time-master-backend.vercel.app
Is it because they both are of different domains? Because my other production build (on windows IIS Server) has two separate sub-domains too but they both work...
As you can see, it does sets the cookie, but on refresh, the cookie gets disappeared and ofcourse I do have credentials: include
in all of my requests.
This works great on localhost but idk what happened after the deployment...
Any of your help would be appreciated. Thanks
After some researching, I got to know that vercel.com
is a public suffix. Which means if the URL is example.vercel.app
then example
here is not a subdomain!
It's totally a different domain, because vercel.app
is the domain extension. Just like many sites have a domain extension like: myuniversity.edu.in
or product.co.uk
snd so on...
The reason why companies like Vercel or Render do this, is because there are thousands of websites hosted on Vercel and so, by default they all will share cookies with each other even if they don't intend to. That's why to solve this supercookie problem, they created .vercel.app
as a public suffix so that this doesn't happen.
So concluding, example.vercel.app
is same as example.com
, that is, they both are entirely different domains. And two different domains cannot share cookies like that with each other, that's why they need to be a subdomain or be one the same domain.
You can also refer to this post by Vercel.
Suppose you made a site named bank.vercel.app
and a user signed into that, and the site cookie is saved at the top level that is, .vercel.app
which means, if I create a site like malicious.vercel.app
and all the user does is just clicking on the link to the malicious site, then that malicious site could read the login cookies of him that got saved from bank.vercel.app
because it's hosted on .vercel.app
domain too.
Now those scammers could easily login to their bank accounts. How crazy is that!
That's why Vercel made .vercel.app
as a public suffix so that your site's cookie won't be compromised by others on vercel domain.
Well, there are two ways to handle this situation:
Send the JWT token through your backend
in a text response in JSON when logging in so that your frontend
could read the token in it easily.
Now on the frontend
side, save the cookie recieved using document.cookie
and on every request you send from now on, just attach the saved cookie to the Authorization header and then send the request to the server.
Now on the backend
side, you have to tweak your middleware code such that it checks the Authorization header of the request coming in, for verifying and reading cookies instead of reading browser cookies like the old way...
A better way would be to buy a domain name and then you will be actually having the same domains or subdomains, or you could also do both of your frontend
and backend
on the same stack. That is, using SvelteKit or NextJS as fullstack to never end up with this issue.
You do whatever you want, the important thing is to make sure you're on the same domain name.