supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
742 stars 184 forks source link

Supabase.initialize don't refresh token after 1h on app open again #906

Open gabrielviannadev opened 7 months ago

gabrielviannadev commented 7 months ago

Describe the bug From 1 week and a couple days ago, we have a problem in our application, basically, before this time, users use login with OTP normally, and have a refresh token automatically, every good.

But now, after this days, when user login with OTP, this generate a valid token, but, if they close and access app again after 1 hour, this is logged out, because the token is no more valid.

The problem is, i use Supase from 1 year, and never have this problem, i use Supabase.initialize all time on start app, and this check if the old token is valid, if not, refresh that. But now, don't work anymore.

Debbuging, i see the client.auth.session <- its comming null on app after this 1hour time.

To Reproduce Only starts Supabase.initialiize, this generate a token in console -> put app closed in background, and re-open after a medium time, this retorn the same token (don't refresh).

Expected behavior The token needs to be refresh when i open app again, when the old token its not valid, and goTrue Session not be null.

Screenshots

Version (please complete the following information): On Linux/macOS I'm using latest version of Flutter, and latest version of Supabase supabase_flutter 2.5.1.

On Windows

Additional context I think explained all infos.

dshukertjr commented 7 months ago

@gabrielviannadev I cannot reproduce this on my end, but are you able to reproduce it? Do you have reliable steps to reproduce every time, or do you see this happening only once in a while?

com8member2 commented 6 months ago

i am also facing the issue but i is not happening consistently but many times when app is opened after some time is gives below error and user gets sign out.

invalid JWT: unable to parse or verify signature, token is expired by 2m5s
I/flutter (18692): #0      GotrueFetch.request (package:gotrue/src/fetch.dart:99:7)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #1      GoTrueAdminApi.signOut (package:gotrue/src/gotrue_admin_api.dart:42:5)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #2      GoTrueClient.signOut (package:gotrue/src/gotrue_client.dart:813:9)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #3      GoTrueClient._callRefreshToken (package:gotrue/src/gotrue_client.dart:1115:11)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #4      GoTrueClient.recoverSession (package:gotrue/src/gotrue_client.dart:928:16)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #5      SupabaseAuth.recoverSession (package:supabase_flutter/src/supabase_auth.dart:86:11)
I/flutter (18692): <asynchronous suspension>
I/flutter (18692): #6      CancelableCompleter.complete.<anonymous closure> (package:async/src/cancelable_operation.dart:425:16)
I/flutter (18692): <asynchronous suspension>
marektomczyk commented 6 months ago

I experience the same problem on my production app - users are randomly logged out from the app. In Supabase logs, I see exactly the same log as @com8member2 included above. Please bump priority on it!

dshukertjr commented 6 months ago

@com8member2 @marektomczyk So this random logout happens not when the user launches the app but when they have the app opened for a long time?

tomekit commented 5 months ago

In our case when app is closed for more than an hour, token expires which is expected. Problem happens when app is started again, we then issue the API request using the most recent JWT (which has expired) which results in API call failing with 403 Forbidden. The: _callRefreshToken logic auto refreshes the token successfully, but new token is received shortly (depending on network conditions etc.) after the initial request was issued.

Perhaps: _refreshTokenCompleter could be exposed, so we could either await on it if it's Future or even run: _callRefreshToken ourselves to ensure that latest JWT is fetched before any API call is made.

Vinzent03 commented 5 months ago

@tomekit What's your use case to manually use the latest jwt? If you are calling supabase endpoints via the sdk, the sdk should try to get a new jwt before making the actual request.

zhangheng2022 commented 4 months ago

Maybe we need an example

tomekit commented 4 months ago

Hi @Vinzent03,

Sorry for late reply. In our case we're using Supabase mostly for auth and then pass JWT to external APIs outside of Supabase ecosystem.

I think it's fair to assume that there are many systems (legacy or not) which would like to integrate authentication mechanism and not necessarily would like to be rewritten using Supabase mindset. Given that JWT integration is extremely easy I think it's rather common use case to "connect" other systems to unified auth system which Supabase's GoTrue is (https://github.com/supabase/gotrue). The current downside is that Supbase doesn't support public keys, so currently sharing secret to external API shares private key, which isn't inherently secure: https://github.com/orgs/supabase/discussions/12759#discussioncomment-9584184) It would be also good to allow optional 2FA JWT verification, we've added that ourselves: https://github.com/supabase/auth/commit/8878f32573d70a3c3e90852dbf613fe2ea5930c8 but that's probably bit offtopic.

My point is, that if Supabase Flutter allows user to access current session:

Session? get currentSession => _currentSession;

it already leaks enough internals (and that's good, because it allows JWT external use) that it should probably allow user to access Future to await to make sure that currentSession is up to date, but that's my opinion only.

Vinzent03 commented 4 months ago

Calling refreshSeession() if the session is expired (session.isExpired) should fix it. It returns the future to the already ongoing request or starts a new refresh.

tomekit commented 4 months ago

Thanks for you reply. I've just double checked our codebase and that's actually what we've been doing already... and in fact it should behave as you describe. Sorry for the confusion caused, we're still getting some intermittent issues with not up to date token, but it seems that this issue likely lies somewhere on our end, as Flutter's goauth library resolved most of these over the past months.

vikrvm commented 2 months ago

Hi, @gabrielviannadev. Did you ever find a solution to this issue? I've run into the same issue when the iOS application tries to update in the background.

dshukertjr commented 2 months ago

@vikrvm Do you have a way to reproduce this issue consistently? That would help us figure out what the root cause is.

vikrvm commented 2 months ago

@vikrvm Do you have a way to reproduce this issue consistently? That would help us figure out what the root cause is.

I do, I have a Swift application I'm working on and this happens frequently. I could send you over a private copy? It's very barebones at the moment but you'll see the logs in the dashboard start throwing token errors after some time.

dshukertjr commented 2 months ago

@vikrvm Is it a Swift or Flutter application running on iOS?

vikrvm commented 2 months ago

@vikrvm Is it a Swift or Flutter application running on iOS?

I'm running into the same issue described in a Swift application using Supabase. I know this is a Flutter specific issue but the description matched my issue exactly also.

dshukertjr commented 2 months ago

@vikrvm Okay, could you open an issue on the supabase-swift repo for that?

ArbazIrshad commented 2 months ago

We are experiencing the same issue too. We are using supabase as our auth service and pass the JWT to our backend. If the user opens the app after 1 hour the token doesn't refresh and user is unable to use our app. But if the user kills the app and opens it again, It starts working again. For now, we are manually refreshing the token.

dshukertjr commented 2 months ago

@ArbazIrshad And this is with supabase-flutter?

ArbazIrshad commented 2 months ago

Yes, Currently facing this issue with supabase-flutter.