Skip to content
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

Support for multiple tabs does NOT respect the 'persistSession' option across tabs #294

Closed
chipilov opened this issue Jun 6, 2022 · 3 comments
Labels
bug Something isn't working

Comments

@chipilov
Copy link

chipilov commented Jun 6, 2022

Bug report

Describe the bug

Supabase's GoTrue JavaScript client has explicit support for multiple tabs which is enabled by default.

Supabase's GoTrue JavaScript client also has support for the commonly-used 'Remember Me' feature via the persistSession parameter of the SupabaseAuthClient constructor.

The issue is that if a user has 2 tabs open - one where the auth client has the persistSession set to false and one where the parameter is set to true - the different tabs will continue to behave differently in terms of persisting the session EVEN though logging from one tab will automatically log-in the other tab.

To me, it seems that it's more logical that once a user logs-in via tab A, all other tabs that get automatically logged-in will inherit the persistSession behavior of the tab A.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Open 2 tabs with a Supabase-auth enabled application - one where persistSession is set to true (let's call this tab A) and one where persistSession is set to false (let's call this tab B)
  2. Sign-in from tab A - notice that tab B detects the sign-in from tab A and now the content in tab B shows info relevant to the user that signed-in via tab A
  3. Close tab A
  4. Continue to work with tab B until the JWT is refreshed at least once
  5. Close tab B and re-open the application in tab C

Expected behavior

The client is still signed-in because when they signed-in originally via tab A, they chose to be remembered (i.e. the persistSession parameter was true);

Actual behavior

The client is no longer signed-in and needs to sign-in again.

Consequences

This behavior can lead to failed token refresh requests because of the re-use of an invalidated refresh token.

This can happen when tab A (as defined above) is closed and its token remains in localStorage while tab B continues to send token refresh requests without updating the token in localStorage. Hence, localStorage will be left with a stale refresh token which will be incorrectly re-used in at least one of 2 cases:

The problem is made worse for users of the library because the library does NOT expose the persistSession config - this means that users of the library can only work around this by inspecting the data in localStorage for which there is also no publicly defined API as far as I can tell.

System information

  • Version of supabase-js: 1.35.3
  • Version of gotrue-js: 1.22.15
@chipilov chipilov added the bug Something isn't working label Jun 6, 2022
@kangmingtay
Copy link
Member

Hey @chipilov, could you please clarify how your application managed to get into a state where the persistSession value on both tabs are different?

Thanks for taking the time to do such a detailed write-up of the issue btw!

@chipilov
Copy link
Author

chipilov commented Jun 8, 2022

Hi @kangmingtay,

In my app, I set the persistSession parameter to false by default (I do this because I prefer the user's explicit approval before I start storing any tokens in the browser). With this setup it's very easy to end up with multiple tabs that have a different value for persistSession, for example:

  1. User opens tab A, loads the app, clicks on the 'Remember Me' checkbox and signs-in. From this point on, tab A has persistSession set to true;
  2. Later, the user opens another tab B and loads the app again (maybe they forgot they already have the app in tab A OR they want another tab so they can look at different things at the same time). As soon as the app is loaded, the user is signed-in (since the constructor of the auth client calls _recoverAndRefresh()), however, the persistSession is actually set to false because that is the default for my app;

NOTE, that you can also get in the same situation even if the default for persistSession is true. Here is an example:

  1. User opens tab A, loads the app and explicitly un-checks the 'Remember Me' checkbox. From this point on, tab A has persistSession set to false;
  2. Later, the user opens another tab B and loads the app again. This time, they are NOT signed-in automatically because there is no token in localStorage to recover from, so they sign-in again but this time they leave the 'Remember Me' checkbox checked, so persistSession is true for tab B. Now they are logged-in in both tabs A and B and the tabs have different values for persistSession.

Let me know if anything is unclear.

@hf
Copy link
Contributor

hf commented Dec 30, 2022

This is behavior that is not something the library can provide. You should synchronize the "remember me" state across tabs manually. persistSession is really a low-level flag that you can use to build complex scenarios like this.

We may consider having some explicit form of "remember me" implemented in the next major version, but that is far away.

@hf hf closed this as not planned Won't fix, can't repro, duplicate, stale Dec 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants