Session based authentication in nodejs [HELP]
Published: 2024-05-07 08:04:00

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

```js
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.
```js
await axios.post(`${baseUrl}/tasks`, payload, {
      withCredentials: true,
      headers: {
        'Content-Type': 'application/json',
      }})
```
Pretty straightforward.

You can view the entire repo [here] (https://github.com/okay-head/task-central).


## 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.
```js
	// 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
> 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](https://developers.google.com/privacy-sandbox/3pcd/storage-access-api), and [Related Website Sets](https://developers.google.com/privacy-sandbox/3pcd/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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oyxxqm1tksnpevrru0c8.png)


### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olxc8tccgj0vpa3e1d1n.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4sbpbmd3tcqa4kioqm18.png)





## 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.