Next.js Discord

Discord Forum

How to make a NextJS app with tab isolated user session?

Unanswered
Thai posted this in #help-forum
Open in Discord
ThaiOP
Hello good people!

I want to create a Next app where the session of a user is tab specific. What I mean by that is opening a new tab will prompt the user to login again. What that means in practice is that multiple app users can be logged in within the same browser window, it's a business requirement.
There is a backend Auth server which will provide a JWT token and another backend service which will provide the data.

Now the problem is I can't save that JWT token in a cookie, as cookies are shared across all tabs for a specific domain. While I can store the JWT in Session Storage, but that means I'll have to fetch the data in the client side as well, because I can't pass the JWT token to the NextJS server side. As a result, I'll have to handle the error boundaries, loading states myself and loose out a lot of benefits of server side rendering.

Is there anyone who has faced similar kind of problem before?
Or is there any way to fetch the data and render in the server?
Any help is appreciated, thanks!

9 Replies

@Thai Hello good people! I want to create a Next app where the session of a user is tab specific. What I mean by that is opening a new tab will prompt the user to login again. What that means in practice is that multiple app users can be logged in within the same browser window, it's a business requirement. There is a backend Auth server which will provide a JWT token and another backend service which will provide the data. Now the problem is I can't save that JWT token in a cookie, as cookies are shared across all tabs for a specific domain. While I can store the JWT in Session Storage, but that means I'll have to fetch the data in the client side as well, because I can't pass the JWT token to the NextJS server side. As a result, I'll have to handle the error boundaries, loading states myself and loose out a lot of benefits of server side rendering. Is there anyone who has faced similar kind of problem before? Or is there any way to fetch the data and render in the server? Any help is appreciated, thanks!
u could give every new authenticated requests (user is logged in) a unique id and bind that to the user in your db and return your jwt with that id and save that in a httponly cookie. You can then save the id in a local state or a global context. U can then use serverside rendering using the cookie. after ssr has finished u can validate the request using the in state saved id.
now when the user opens a new tab and the server sends data the user will be logged out since the returned state id from the server and the state id in the state is not the same
to be honest its a very strange business requirement that u have
@gin u could give every new authenticated requests (user is logged in) a unique id and bind that to the user in your db and return your jwt with that id and save that in a httponly cookie. You can then save the id in a local state or a global context. U can then use serverside rendering using the cookie. after ssr has finished u can validate the request using the in state saved id. now when the user opens a new tab and the server sends data the user will be logged out since the returned state id from the server and the state id in the state is not the same
ThaiOP
Thank you for taking the time to reply.

I agree it's a bit of a weird requirement, but I don't make the rules! 🙁

The business requirement is that a user session can't span over multiple tabs. In that way a person having two accounts can log in simultaneously in two different tabs with different user credentials in the same browser.

Let's say a person has two different user accounts.

Now, after logging in in Tab A, the person will receive an auth token. Same will happen when the person logs in in another tab with the other user account that they have. I can save these tokens in Session Storage, that solves the problem of a session not spanning multiple tabs, however I don't have the ability to send these JWT to the Next server then.

If I use cookie to save the JWT, then the second opened tab of the web app will already have that cookie of the first account.

That's the problem I have.
Hey, I just thought of this idea but never used it, consider if you like it

You can keep all the JWTs for all logged-in accounts in local storage.
And keep a session variable called currentUser with JWT for the currently logged-in user
sessionStorage.setItem("currentUser", JWT)

If the above variable is not set i.e. if
sessionStorage.getItem("currentUser")
is null (will happen initially when a new tab is opened) then you can show a modal listing all the accounts associated with the JWTs that are stored in local storage to log in as and then set the "currentUser" variable in sessionStorage of the selected user.
@gin why dont u extend fetch and write a wrapper that always takes in the jwt if there is one and sends it in the request?
ThaiOP
Yeah, that's possible on the client side only.

Client -> Next Server -> Backend
I want this to work.

Even if I extend fetch and set the JWT somewhere there it has to be from the client side, meaning,

Client -> Backend

But by doing this I can't render anything on the server at all.

Is there any way you can think of that let's me send user session specific JWT from client to Next Server? i.e.,

Client -> Next Server

Then I can fetch the data on the Next server and render the page on the server.
You can do something like an API endpoint that sets a httpOnly cooking in response

And you can call them
i) initially when new tab is opened and a user is selected for that tab (send the 'currentUser' from session to the API
ii) Whenever a tab is focused, you call the API to update the cookie with that accounts jwt (just make sure that the focus event listener & API response is fast enough that when user tries to perform any action it's from a correct account)