fix: refreshing tokens at the wrong time #55
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
StoredSession.isValid was being calculated incorrectly, because by comparing to "1 minute ago", it means an access token which expires "30 seconds ago" is still valid for 30 seconds. Changing to plus 60 seconds eliminates this problem, and bakes in plenty of time for latency issues.
In a future evolution I believe this value should be configurable.
What kind of change does this PR introduce?
This fixes is a critical bug in the token refresh logic, by ensuring refresh tokens are refreshed before they become expired.
What is the current behavior?
The logic to calculate if a stored access token is valid is flawed and results in consistently getting expired access tokens from
await auth.session
if it's within 60 seconds of expiring.The current logic is:
isValid = expirationDate > Date().addingTimeInterval(-60)
In other words, a token is valid if its expiration date is later than a minute ago.
So let's say you have an access token which expires at 11:59:50.
And let's say you call
await auth.session
at 12:00:00. (hh:mm:ss)isValid
is then calculated as11:59:50 > (12:00:00 - 60)
, or11:59:50 > 11:59:00
.So,
isValid
is true even though actually the token expired 10 seconds ago.What is the new behavior?
The new behavior changes the
isValid
calculation from subtracting 60 seconds from "now" to adding 60 seconds. This means the access token returned fromauth.session
will be guaranteed to be valid for at least 60 seconds. In a future evolution this could be a user-configurable value, but it's important it's greater than 0 or you will consistently get expired access tokens if you ask for one in <60s from when it expires. Being greater than 0 (rather than just 0) has the benefit of being proactive about the token, meaning it handles any server latency etc that could arise as you attempt to use the token.Additional context
For context, my app which uses Supabase would 401 requests seemingly randomly. Then I realized it was happening every hour, which I realized is what I set my auth token expiry time to. This change fixes it!
Fixes #53