next-auth: NextAuth should not invalidate the client-side session when the browser is offline
Description š
NextAuth invalidates the client-side session when the browser is offline and the NextAuth client cannot communicate with the NextAuth backend. From an application perspective, the expectation is that the NextAuth library must provide the last-known session state unless session TTL runs out or the NextAuth client receives an authoritative response from the NextAuth backend.
How to reproduce āļø
git clone https://github.com/nextauthjs/next-auth.git
cd next-auth
cp app/.env.local.example app/.env.local
npm install
npm run dev:setup
npm run dev
- Open http://localhost:3000/protected in Chrome
- Sign In with credentials using āpasswordā as password
- Observe that the page says āThis is protected content. You can access this content because you are signed in.ā
- Open Chrome dev tools Network tab and select the āOfflineā mode
- Minimize the browser window
- Restore the browser window
- Observe that the page says āAccess Denied. You must be signed in to view this pageā
Screenshots / Logs š½
Logs in browser console:
react_devtools_backend.js:2560 [next-auth][error][client_fetch_error]
https://next-auth.js.org/errors#client_fetch_error session TypeError: Failed to fetch
asyncToGenerator.js?1da1:6 Uncaught (in promise) TypeError: Failed to fetch
Environment š„
System:
OS: macOS 11.4
CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
Memory: 1.37 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.17.1 - /usr/local/bin/node
npm: 6.14.13 - ~/Temp/next-auth/node_modules/.bin/npm
Browsers:
Chrome: 91.0.4472.106
Firefox: 89.0
Safari: 14.1.1
Contributing šš½
Iām more than happy to author a PR but Iām just not sure about the logic behind https://github.com/nextauthjs/next-auth/blob/5a89ab69d3ceee2f84b683b6fa67455126f80815/src/client/index.js#L106 Is there any specific reason to force clientMaxAge=0 session re-validation on keep-alive timer or visibilitychange events? IMO clientMaxAge=0 session must be presumed valid unless the backend says the session is no longer valid (which would be triggered by āstorageā event).
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 7
- Comments: 29 (15 by maintainers)
@jozefhruska, the
refetchWhenOffline
option does an excellent job at hiding this issue in most cases, but it doesnāt eliminate it since it doesnāt fix the root cause. It just makes this issue less frequent but even more challenging to reproduce and troubleshoot, which is a poor customer experience in my books.Here is a simple demo illustrating this issue - https://pnlkxs-3000.preview.csb.app (source code)
And here is the same demo with a patched
next-auth
version that does not exhibit this issue - https://m7219t-3000.preview.csb.app (source code)Iāve updated my project to next-auth@4.10.3 today, and unfortunately, v4 handles unreliable network conditions even worse than v3. It takes just one
/api/auth/session
network request to fail, and next-auth flips the session to null and completely stops trying to re-fetch the session (even whenrefetchInterval
is defined).Here is an updated patch for v4: https://gist.github.com/igordanchenko/e1e40c2da14ccdc2823c7fc31a5b2de2
This patch changes next-authās bail-out-on-any-network-error implementation to use-stale-while-revalidate semantics. With this patch, the
useSession
hook consistently returns the last known session state regardless of network errors (browser offline, flaky network, DNS issue, routing issue, backend temporarily offline, etc.)Installation:
./patches/next-auth+4.10.3.patch
(the actual file name will be changing as I keep updating the patch for newly released versions)Patch source code: https://github.com/igordanchenko/next-auth/commit/0918a5fbbfd7e11e9d0996fe49ccf27cd81ab375
Thanks for pointing me to that enhancement. However, the more I think about this, the stronger I feel that current behavior is incorrect. And to be clear, my main concern is with the way NextAuth handles network failures / offline mode and not the āvisibilitychangeā event.
Letās imagine you have an email client app that uses the following session settings:
These settings establish the following contract: a) letās use session data on the client for up to 120 minutes before considering it stale b) and also letās ping the server every 5 minutes to renew the session and reset the 120-minute rolling window
But what is happening is that NextAuth evicts client-side session data even when a single keep-alive call to the server fails and returns no fresh data.
Now imagine you are commuting to work by train reading emails, and all of a sudden, your favorite email app tells you āHey, your session is no longer good, and you need to sign in againā all just because the train went through a tunnel and you were offline for couple minutes. This is a bad user experience in my books, and I do not see a clear way for an app developer to work this around unless NextAuth correctly handles failed keep-alive / session refresh calls.
What are your thoughts on this?
Some options to handle offline-ness would be pretty helpful. A few of my users have complained about being sporadically logged out when they are on patchy internet.
I ended up solving this with useSWR https://github.com/nextauthjs/next-auth/issues/596#issuecomment-760251882
Here is code sandbox example using swr and react-query - https://codesandbox.io/s/nextauth-2215-gxoks
With both libraries the app stays mounted and displays previously fetched data.