I have a React app which uses Supabase for authentication.
I'm wondering, is it best practice to store a user's session in client-side state (e.g. setState
or the like) in order to avoid making an API call every time a component would like to know if a user is logged in? The isSignedIn
function on the auth context currently looks like this.
isSignedIn: async () => {
// If there's a valid session object, yes, we're logged in
if (!!session)
return true
// If we don't have truthy value for session, check with the server
// and return appropriately
let { data } = await client.auth.getSession()
if (!!(data?.session)){
setSession(data.session)
return true
}
}
Though the tricky part here is, as long as there's something in the session
state the app considers the user logged in despite the server having potentially ended the session.
It seems to me like this is essentially a cache invalidation issue and I'm leaning toward removing the storing of the session in client-side state. Instead I'll just make an API call every time.
Should I avoid storing the session in app state in favour of making an API call every time, or is my solution just implemented badly?
Also, if all I have now is this async isSignedIn
function on my auth context, how do I use it? I'm guessing I can't just use it in the render function of, say, for instance a <ProtectedRoute />
component -
return authContext.isSignedIn() ? children : <Navigate to="/sign-in"/>
It seems like I'd have to use it within useEffect
, storing the result in some state of the component which seems like I'm now back at the start (storing the result in some state).
The recommended pattern is to use onauthstatechange
to update the session in state, e.g. see https://github.com/supabase/supabase/blob/master/examples/user-management/react-user-management/src/App.js#L15-L18
supabase.auth.onAuthStateChange((_event, session) => {
setSession(session)
})
}, [])