-
-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically refresh access token before it expires #78
Conversation
if (accessToken) { | ||
supabaseClient.auth.setAuth(accessToken); | ||
setAccessToken(accessToken); | ||
} | ||
if (refreshToken && expiresAt) { | ||
setRefreshToken({ token: refreshToken, expiresAt }); | ||
} | ||
setUser(user); | ||
if (!user) setIsLoading(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there's some double-handling of isLoading
in this component – it's set in checkSession
, and in the two useEffect
hooks that call checkSession
. Seems worth cleaning up, but I didn't want to muddy this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I'm thinking about it, it seems strange to set isLoading
to true
on subsequent reloads of the user (after the first load). If you think about how isLoading
would be used practically, it'd be to show loading states etc on an initial page load. As a consumer of the hook, I wouldn't expect isLoading
to then flick back to false then true again every time the user is refreshed – it'd cause loading states to briefly pop back in, which would be strange
Thanks for this. I think the setTimeout itself, isn't enough though. Maybe needs to be paired with something like #35 ? Also, we shouldn't refresh the token on the client-side, but rather on the server-since the cookies are the source of truth and we don't want them to become out of sync. So rather than calling |
I think the issue with #35 is that it allows the token to expire, meaning if the user comes back to the page after it's expired, there's a chance that requests might be sent with an expired token before the refresh is completed. As an example, my app uses SWR, which I've configured to refresh data when the page becomes visible again (as is a common pattern). This would mean the page data refresh and the token refresh would happen at the same time, and the former would fail.
With this PR, they won't get out of sync as calling That said, I could understand the design choice to avoid reading refresh tokens in the client, and instead let the handlers pull them out of cookies and complete the refresh there. As it stands, calling Though we'd still need to know the |
I'm not sure this PR breaks that principle (which I agree with) – it's reading the refresh token from the cookies then using it in the frontend in the same way that the access token is being used. It's not being updated elsewhere - only in the cookies |
I think @GaryAustin1 has a more robust fix as its at the gotrue-js level supabase/supabase#6464 |
@silentworks, AFAICS @GaryAustin1 solution is for client-side refreshes when the tokens are managed in localStorage. With the auth helpers, token management is moved to the server-side via cookies, so the refresh would need to happen there so that tokens don't get out of sync. Since we're moving away from storing tokens in localStorage in the future, I'd prefer to have the auth helpers not rely on this part of |
All,
|
Yes, it's happening on a timer because of realtime. See some suggested improvements here: supabase/auth-js#274 |
This has been added in #92 |
Addresses #73
Uses a similar timeout mechanism to
gotrue-js
'sautoRefreshToken
function, but simplified.With the
refreshToken
available in the frontend after the first commit, it could theoretically be passed to thesupabaseClient.auth
instance so that we can use itsautoRefreshToken
function, but the only current interface for setting therefreshToken
issupabaseClient.auth.setSession(refreshToken)
, which triggers a refresh of the token, which we don't want. So the (arguably cleaner) alternative is to handle the refresh withinUserProvider
.