In many of my previous projects with auth I used localstorage or sessionstorage to store the JWT. Trying to use http only secure cookies, the only issue I am running into is trying to a seperate header component from a login component.
For example, using localstorage or sessionstorage I would often have a header component that looks like:
function Header() { if (localStorage.getItem('user') == null) { return ( <div className="Header"> <Link to='/'>Home</Link> <Link to="/Login" >Login</Link> <Link to="/Register" >Register</Link> </div> ) } return ( <div className="Header"> <Link to='/'>Home</Link> <button onClick={logout}>Logout</button> <Link to='/cart'>Cart</Link> </div> ) }
With the above component, after you signed in (in a seperate component) this would be updated immediately or as soon as the JWT was saved to localstorage. Now since the client does not have access to the httponly secure cookie what would be the best way to do this?
Initially I thought using context to have a isloggedin variable that gets changed to true after signing in however the variable would get reset on refresh.
Thus my second thought would be to have the header have its own use effect to check against the server to see if the cookie/jwt is still valid. The problem with this I think would be that since header is a seperate component on each page every page you navigate to would be requesting the data over and over perhaps unnecessarily.
My third thought would be to have a use effect or query at a higher component and any interaction on the page would result in the entire page checking if the cookie has not expired, with maybe each of the child components getting an isloggedin var like in option one.
My final thought was merely using an httpcookie alongside something in session storage that tells the components whether to display data regarding a logged in user or not, but this approach seems like it could result in inconsistency if somehow the cookie validated but the session storage did not communicate that.
I am not sure which is the best approach or if there is a better one or more common / best practice way to do this as each method I thought of seems to have its flaws.
Advertisement
Answer
I would go with keeping separate information about the logged-in user in either the memory or session storage. You could just keep an isLoggedIn
flag and maybe the username to display a greeting, etc. If you want to keep that information in memory, not session storage, then you can have an effect that will fire on every page refresh and ask your backend for the login state of the user. Such a request will send the cookie to the backend, and the backend can respond with information about whether the user is logged in and their username.
but this approach seems like it could result in inconsistency if somehow the cookie validated but the session storage did not communicate that.
I think you don’t have to be concerned with inconsistencies. If the user is logged in, but your front will not have that information then you will display a “log in” button, and the user will be automatically logged in when they click. If the user’s session would expire, but you will still have information that they’re logged in, then you will get a 401 response when calling your backend. You can then catch such a response and update the user’s state in your front.