Skip to content

Custom LocalStorage logs out user instead of refreshing session #895

Open
@micheltucker

Description

@micheltucker

Describe the bug

I need to maintain a Custom LocalStorage and followed the description here: https://pub.dev/documentation/supabase_flutter/latest/#a-idcustom-localstorageacustom-localstorage

I am encountering a recurring issue in my iOS Flutter application that integrates Supabase with custom LocalStorage for authentication. Specifically, when attempting to automatically recover a user session after the application has been in the background, the refresh token fails with an "Invalid Refresh Token: Already Used" error. This error is consistently triggering a sign-out event, effectively logging the user out and hindering session persistence across app launches or background returns.

To Reproduce
Steps to reproduce the behavior:

  1. Log in to the application to initiate a session with Supabase.
  2. Send the application to the background for an extended period or until the access token is likely expired.
  3. Resume the application, triggering the automatic session recovery process.
  4. Observe that instead of refreshing the session, an error occurs, and the user is signed out.

Expected behavior
The application should silently refresh the session using the stored refresh token when the access token has expired, without any intervention from the user, maintaining the user's logged-in state across app uses. This works for the default localstorage of Supabase.

Actual beheavior
When attempting to refresh the session, the application signs out and throws an "Invalid Refresh Token: Already Used" error, resulting in the user being signed out. The relevant log outputs are as follows:


flutter: **** onAuthStateChange: AuthChangeEvent.signedOut
flutter: Auth state change detected
flutter: AuthException(message: Invalid Refresh Token: Already Used, statusCode: 400)
flutter: #0      GotrueFetch.request (package:gotrue/src/fetch.dart:99:7)
flutter: <asynchronous suspension>
flutter: #1      GoTrueClient._callRefreshToken (package:gotrue/src/gotrue_client.dart:1087:24)
flutter: <asynchronous suspension>
flutter: #2      GoTrueClient.recoverSession (package:gotrue/src/gotrue_client.dart:928:16)
flutter: <asynchronous suspension>
flutter: #3      SupabaseAuth._recoverSupabaseSession (package:supabase_flutter/src/supabase_auth.dart:127:7)
flutter: <asynchronous suspension>
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: AuthException(message: Invalid Refresh Token: Already Used, statusCode: 400)
#0      GotrueFetch.request (package:gotrue/src/fetch.dart:99:7)
<asynchronous suspension>
#1      GoTrueClient._callRefreshToken (package:gotrue/src/gotrue_client.dart:1087:24)
<asynchronous suspension>
#2      GoTrueClient.recoverSession (package:gotrue/src/gotrue_client.dart:928:16)
<asynchronous suspension>
#3      SupabaseAuth._recoverSupabaseSession (package:supabase_flutter/src/supabase_auth.dart:127:7)
<asynchronous suspension>
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: AuthException(message: Invalid Refresh Token: Already Used, statusCode: 400)
#0      GotrueFetch.request (package:gotrue/src/fetch.dart:99:7)
<asynchronous suspension>
#1      GoTrueClient._callRefreshToken (package:gotrue/src/gotrue_client.dart:1087:24)
<asynchronous suspension>
#2      GoTrueClient.recoverSession (package:gotrue/src/gotrue_client.dart:928:16)
<asynchronous suspension>
#3      SupabaseAuth._recoverSupabaseSession (package:supabase_flutter/src/supabase_auth.dart:127:7)
<asynchronous suspension>

Version (please complete the following information):
├── supabase_flutter 2.3.4
│ ├── supabase 2.0.8
│ │ ├── functions_client 2.0.0
│ │ ├── gotrue 2.5.1
│ │ ├── postgrest 2.1.1
│ │ ├── realtime_client 2.0.1
│ │ ├── storage_client 2.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    authThis issue or pull request is related to authenticationbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions