DEV Community

Cover image for Session based authentication in nodejs welp
Shashwat jaiswal
Shashwat jaiswal

Posted on • Edited on

Session based authentication in nodejs welp

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.

  1. Create a basic express app, a react frontend
  2. Connect mongodb
  3. Add routes, controllers, models et cetra
  4. 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,
    })
)
Enter fullscreen mode Exit fullscreen mode

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

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

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)
Enter fullscreen mode Exit fullscreen mode

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

Cookies with sameSite: none are third party cookies

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.

CSRF attacks

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

Image description

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.

Image description

Image description

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.

Top comments (0)