So I've implemented facebook login using Passport-js. I've also implemented Cookie-strategy for using good ole username/password login. My setup is Express-js backend and a React front-end. Backend and frontend runs on different servers and domains(backend-client.com, frontend-client.com).
Everything works like a charm on localhost but not in stage and production environment. Don't know if it matters but I'm using Heroku for hosting my applications.
The issue:
When the facebook authentication is complete, the Express server redirects the user to the frontend app. The cookie is a JWT containing user info to check if the user is logged in.
const cookieSettings = {
domain: process.env.COOKIE_DOMAIN,
secure : (process.env.APP_MODE === 'local' ? false : true),
httpOnly : true,
};
const cookieMaxAge = {
maxAge : 14 * 24 * 60 * 60 * 1000 // 14 days, 24h, 60 min, 60 sec * miliseconds
}
router.get('/auth/facebook/', passport.authenticate('facebook'));
router.get('/auth/facebook/callback', function(req, res, next) {
passport.authenticate('facebook', async function (err, profile, info) {
if (err || !profile) {
res.redirect(`${process.env.FRONTEND_BASE_URL}?success=0`);
}
const user = await User.findOne({ facebookId : profile.facebookId });
return user.generateAuthToken().then((token) => {
res.cookie(COOKIE_NAME, token.token, {...cookieSettings, ...cookieMaxAge});
res.redirect(`${process.env.FRONTEND_BASE_URL}?success=1`); // redirect back to frontend-client with cookie
});
})(req, res, next);
});
When the user hits /auth/facebook/callback the cookie is present
However when the user returns to the frontend client no cookie is sent in the response headers.
I can't wrap my head around this. I'm I missing some fundamentals around cookies?
Side note: When the user logs in using username and password the cookie is returned to the user. The login method is created using ajax-request with Axios if it matters. So I know there's no issue with the cookie settings I'm using.
So after a week or so it turns out it was a Heroku domain issue. I was using multiple Heroku domains for my frontend and backend apps(backend.herokuapp.com, frontend.herokuapp.com).
According to Heroku documentation
In other words, in browsers that support the functionality, applications in the herokuapp.com domain are prevented from setting cookies for *.herokuapp.com
I solved my issue by adding a custom domain to my apps(backend.mycustomdomain.com, frontend.mycustomdomain.com) and the cookie was in added to the client from the server-response
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With