Session based authentication in nodejs [HELP]

Session based authentication in nodejs [HELP]

You need authentication in nodejs.

JWT is a half-baked solution. Don’t pretend it is secure because it is popular.

Either way you need to learn session based authentication once and for all.

Setup

The basic MERN app setup.

Create a basic express app, a react frontend
Connect mongodb
Add routes, controllers, models et cetra
Connect to mongo via atlas, host db (render.com), host your frontend (netlify).

My cors config in server.js looks like this

app.use(
cors({
origin: your site,
methods: [GET, POST, PATCH, DELETE],
allowedHeaders: [Origin, Content-Type, Accept],
credentials: true,
})
)

Also, on the frontend, requests are sent with the credentials flag.

await axios.post(`${baseUrl}/tasks`, payload, {
withCredentials: true,
headers: {
Content-Type: application/json,
}})

Pretty straightforward.

You can view the entire repo here.

Authentication

Spoiler.

Mind f##k.

For simplicity, we’ll only talk about login here.

Every time I login, meaning after all the validations have passed and I finally move to the code where the session for the user needs to be created and stored. I do it with this logic.

// finally login and create a session
const session_id = crypto.randomUUID()
res.cookie(session_id, session_id.toString(), {
maxAge: 86400000,
httpOnly: true,
secure: true,
sameSite: none,
partitioned: true,
// sameSite: ‘strict’,
})
addSession(session_id, doc._id)

The addSession is a helper function that uses the native crypto package to register a session in the server memory.

So auth is straightforward.

Frontend creds -> validations -> set cookie in headers as a response -> the client sends that cookie w every request, making it clear that it is signed in

sameSite attribute

Notice that I’ve the sameSite:’strict’ property commented out. This is because my frontend and backend are on different domains, so this is a cross-site request according to CORS and will naturally get blocked.

But this brings with it, it’s own set of problems.

XSS attacks, CSRF attacks and more.

Not to mention, Chrome won’t even ALLOW my cookies now. This is because I’ve got third party cookies blocked.

But there’s a way to solve this problem.

CHIPS

As of 2024, Chrome has started a gradual blockage of 3rd party cookies.
Cookies with sameSite=none; Secure and Partitioned attribute unset operating in cross-contexts are now counted as third party cookies and CHIPS, the Storage Access API, and Related Website Sets are the only ways to read and write cookies from cross-contexts.

This can be a real problem if your server is on a different domain than your websites.

This can be a real problem if your server is on a different domain than your websites.
CHIPS or Cookies Having Independent Partitioned State.
Basically set the partitioned attr to true in your cookie options and voila it should work.

Express bug

Unfortunately, it’s not always roses and sunshine.

res.cookie() has a bug which doesn’t set the partition attribute. So my code above, doesn’t set the partitioned attribute to true in the response header.

Browser behaviours

Here are the errors that I’ve encountered.

Firefox

In firefox, it somehow works
Even though I’ve got my third party cookie blockage set to true. This might even be a firefox bug.

It shows this warning

Chrome

In chrome, with 3rd party cookies blocked. Nothing works.
Sessions authentication will not work. Period.

However with 3rd party cookies enabled, I get this warning.

Conclusion

I just wanted to implement session based authentication.

GET requests will work, regardless of even if sameSite is set to strict (i guess). But what do i do now.

Either express fixes the cookie issue

or

I find a way to bypass cors altogether.

either way, stackoverflow

here I come.

Leave a Reply

Your email address will not be published. Required fields are marked *