Cookie not transferred after redirect in OAuth2 implementation (works in Chrome, fails in other browsers)

2 days ago 8
ARTICLE AD BOX

I have an application with my Express server hosted on Render and my React frontend hosted on Vercel. I'm implementing OAuth2 with Google and setting the access token into the oauth_token cookie after successful authentication. Afterward, I redirect the user to the frontend using res.redirect().

What works:

The cookie is set and passed correctly when tested on Chrome.

The problem:

On other browsers, the cookie seems to be set properly from the /callback endpoint, but when redirecting to the frontend (the /dashboard route), subsequent requests don’t contain the cookie.

When sending a request like /random on the backend, the cookie is set correctly, but for some reason res.redirect() is preventing the cookie from transferring to the frontend.

Callback response with cookie set:

Callback Response with Cookie Set

No cookie on redirect to /dashboard:
No Cookie on Redirect /dashboard

Cookie set when visiting /xyz on backend:

Cookie Set When Visiting /xyz on Backend


Here is my code:

Inside /user/oauth/callback:

res.cookie("oauth_token", accessToken, { maxAge: 0.95 * 60 * 60 * 1000, httpOnly: true, sameSite: "none", secure: true, }); res.redirect(`${env.FRONTEND_URL}/dashboard`);

Inside index.ts:

app.use( cors({ origin: env.FRONTEND_URL, credentials: true, methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], allowedHeaders: ["Content-Type", "Authorization"], }) ); app.use(cookieParser());

What I've tried:

1. Redirect using JavaScript

Looked at https://github.com/expressjs/express/issues/4416

res.cookie("oauth_token", accessToken, { maxAge: 0.95 * 60 * 60 * 1000, httpOnly: true, sameSite: "none", secure: true, }); res.send(` <!DOCTYPE html> <html> <head><title>Redirecting...</title></head> <body><script>window.location.replace("${env.FRONTEND_URL}/dashboard");</script></body> </html> `);

2. Adding the domain option to the cookie:

res.cookie("oauth_token", accessToken, { maxAge: 0.95 * 60 * 60 * 1000, httpOnly: true, sameSite: "none", secure: true, domain: "frontend.com", });

3. Adding the expires tag after looking at Send a set-cookie header to a redirect url in node.js.

expires: new Date(Date.now() + 24 * 60 * 60 * 1000)

There was also a comment in the same thread saying that in Express version 4.16.3 you must call res.cookie() before res.redirect(), which I already have in my code.

Read Entire Article