I am writing an application using a C# backend and a Vue frontend, and I am a bit sceptical about where is best to store information about the user that is currently logged in.
There are a few posts on here about this, but none of them really have a consensus, everyone is saying different things and I’m not quite sure which is actually recommended, or which people just due and forget about the potential security issues that could arise because of it.
For context, I am talking about stuff like the users name, which I want to show in the header on all pages. My current flow is that user logs in > send request to C# backend > backend returns a JWT which utilises a Pinia store and also stores the JWT as a cookie.
There are a few people on here who are saying that its perfectly acceptable to store names etc in a JWT, but that doesn’t sound like a good idea to me? I thought about potentially just using the store, but that would be problematic for when refreshes happen and when the browser is closed as the user would be logged out.
What would be the recommended way to go about this? Just to return a JWT with a user id or something, and then send that to the API on every single page load? That seems a bit excessive and an additional overhead that isn’t needed? I also thought about potentially just setting a session id in the cookie instead of a JWT and sending an API response every time the page loads (which would allow me greater control over invalidation etc, but also comes at the expense of additional backend requests.
3
There seem to be two questions here.
- How to store UI information that’s required for display, For example Username, User profile picture, other User preferences that might need to be displayed on every Page in a Header of some kind.
- How to correctly use a JWT returned by the backend.
1. You can persist the local state in localStorage or sessionStorage
This is where I’d recommend storing the UI Information you need. This should mostly be things like ‘Username is Jane Doe’, ‘User has this avatar’ or ‘User prefers website in Darkmode’. You’ll need this on every single page to show it in headers and co, but it’s not extremely sensitive. You should GET this information once on page load and then save it in the store. From there you can persist it to sessionStorage or localStorage, using for example the ‘pinia-plugin-persistedstate’ Plugin for Pinia or just plain javascript.
Of course, sometimes being logged out when you close the browser is the right move, depending on how sensitive your application is.
2. You should send the JWT on any request to an endpoint that requires auth
You wrote that
then send that [JWT] to the API on every single page load? That seems a bit excessive and an additional overhead that isn’t needed?
Every endpoint that’s not open to the public needs the JWT (or some other authorisation mechanism) to verify you’re allowed to access it. That’s not excessive, that’s the base idea behind the technology and ensures you’re stateless. Now, you could go stateful in theory, but REST for example assumes you’re stateless, and it makes scaling a lot easier to be stateless so I’d strongly advice for it.
Sidenote, remember that JWT is not encrypted and should only be sent over a secure connection.