even for refreshing
# support-questions
r
Is it possible to subscribe to events such as refreshing a token on the frontend sdk? The use case is mostly around having a reactive state so that consumers could always use the latest JWT
r
hey @Random When you call session.getAccessTokenPayloadSecurely() on the frontend, it will auto refresh is needed, so you don't really need to do this. But in case you still want to, we do fire events for this: https://supertokens.com/docs/session/advanced-customizations/frontend-hooks/handle-event
Copy code
import Session from "supertokens-auth-react/recipe/session";

Session.init({
    onHandleEvent: (context) => {
        if (context.action === "SIGN_OUT") {
            // called when the user clicks on sign out
        } else if (context.action === "REFRESH_SESSION") {
            // called with refreshing a session
            // NOTE: This is an undeterministic event
        } else if (context.action === "UNAUTHORISED") {
            // called when the user doesn't have a valid session but made a request that requires one
            // NOTE: This event can fire multiple times

            if (context.sessionExpiredOrRevoked) {
                // the sessionExpiredOrRevoked property is set to true if the current call cleared the session from storage
                // this happens only once, even if multiple tabs sharing the same session are open, making it useful for analytics purposes
            }
        } else if (context.action === "SESSION_CREATED") {
            // Called when session is created - post login / sign up.
        } else if (context.action === "ACCESS_TOKEN_PAYLOAD_UPDATED") {
            // This is called when the access token payload has been updated
        }
    }
})
r
Thanks for the response. Using
session.getAccessTokenPayloadSecurely()
works as intended but if the token is refreshed and we need to update the websocket authentication header, it will not know as there's no dependency that has changed. I think using the event system that you've posted might be useful as i might be able to update everything that depends upon the last jwt (the idea is just to provide awareness even though the components might invoke
session.getAccessTokenPayloadSecurely()
)
r
fair enough.
r
@rp I'm sorry for pinging you directly, i'm getting back on this topic as i've been playing around with the event handler API. Is there a way for the payload contents to actually include the "new" token instead of manually invoke
Session.getAccessTokenPayloadSecurely
?
r
i don't quite understand. When you call
Session.getAccessTokenPayloadSecurely()
, it will refresh the session if required and add the latest jwt into it.
r
Right now the action payload does not bring the latest token once its refreshed/created, all i was asking is if there's a way for me not to have to invoke
Session.getAccessTokenPayloadSecurely()
as what i can about is the JWT to forward to websockets/apollo client. There's no reactive state with the default Session recipe. Let's say you have a websocket connection and at some point you're JWT expired and goes into the refresh flow. The websocket exchange will fail if it doesn't get the latest JWT which i can get from
Session.getAccessTokenPayloadSecurely()
but i've seen sometimes refresh happening right after the session is created 🤔
r
so ideally, you should always call
await Session.getAccessTokenPayloadSecurely()
when adding the JWT to the socket event. Always. > but i've seen sometimes refresh happening right after the session is created This is odd, and shouldn't happen. How can we reproduce this?
r
@rp I was just double checking if there was a way to have a reactive jwt as if you construct your websocket and pass the Authorization Bearer, you'll be able to have a stale jwt. I think what i'm trying to say is we need a "signal" which is the event handler so that the websocket/apollo factory can actually invoke
Session.getAccessTokenPayloadSecurely()
. If you had to construct a React component that creates an apollo client, how would you guarantee that the token is always up-to-date? 🤔 (not even bringing the possibility of memoization as it would require having jwt as a dependency)
I'll try to explain myself better, the problem statement would be: Given a React component that has an expensive provider which requires as a dependency the "JWT", how can we guarantee that after the refresh/sign out the token will be reflected automatically to that consumer?
The current solution that i have is having a global store (zustand store) that is always up-to-sync with the Session event handler, so if you sign out or update the token it will reflect to that global store resulting in a reactive state
r
you need to call
await Session.getAccessTokenPayloadSecurely()
, and that's really the only way to guarantee.
r
If you build a react hook/memo and invoke that method, it will end up stale if the token is refreshed, i'm i not correct? The result value is not an reactive state, it's just a promise result that once its memoized, it's memoized
If you prefer i can build up a quick GH repo and demo the JWT being stale just invoking
Session.getAccessTokenPayloadSecurely()
in a dumb react component, you'll see that once the refresh flow/sign ou kicks in, the initial hydrated state that i was able to get using that Session method will never be in sync
r
yea, that's correct. I know what you mean
therefore, you should call
await Session.getAccessTokenPayloadSecurely()
as late as possible - when you are making the network request.
r
How would you do that in a websocket initial handshake unless the client is not either re-built (e.g: using memo) or exposes some event handler to exchange? 🤔
Btw my solution works as we end up having JWT being a reactive state but the request here is whether its possible on events such as
SESSION_CREATED
having the JWT/payload included
r
> How would you do that in a websocket initial handshake Can i see code related to this?
r
Sure, once i can i'll try to create a repo and share with you
r
thanks!
3 Views