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

Refreshing expired session token by calling api.sessionToken() is broken #97

Open
rolandtolnay opened this issue Jan 16, 2025 · 1 comment · May be fixed by #109
Open

Refreshing expired session token by calling api.sessionToken() is broken #97

rolandtolnay opened this issue Jan 16, 2025 · 1 comment · May be fixed by #109
Assignees
Labels
bug Something isn't working clerk_auth package: clerk_auth
Milestone

Comments

@rolandtolnay
Copy link

rolandtolnay commented Jan 16, 2025

Steps to reproduce

  1. Authenticate with a user using an Api instance
  2. Wait 60 seconds for initial session token to expire
  3. Call api.sessionToken()

Expected results

As per documentation, session token should be refreshed

Actual results

Backend POST request returns a 401 with the following error:

{"errors":[{"message":"Signed out","long_message":"You are signed out","code":"signed_out"}],"clerk_trace_id":"4f2983677823b804881b8ad02f68908c"}

Code sample

Code sample
import 'package:clerk_auth/clerk_auth.dart';
import 'package:flutter/material.dart';

class SampleApp extends StatefulWidget {
  const SampleApp({super.key, required this.publishableKey});

  final String publishableKey;

  @override
  State<SampleApp> createState() => _SampleAppState();
}

class _SampleAppState extends State<SampleApp> {
  late final Api api;

  @override
  void initState() {
    super.initState();
    api = Api(publishableKey: widget.publishableKey);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: [
              ElevatedButton(
                onPressed: () async {
                  final response = await api.createSignIn(
                    identifier: '<EMAIL>',
                  );

                  final signIn = response.client!.signIn!;
                  await api.attemptSignIn(
                    signIn,
                    stage: Stage.first,
                    strategy: Strategy.password,
                    password: '<PASSWORD>',
                  );
                },
                child: Text('Sign in'),
              ),
              ElevatedButton(
                onPressed: () async {
                  // Wait 60 seconds for initial session token to expire
                  final token = await api.sessionToken();
                  print(token);
                },
                child: const Text('Print session token'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration Image

Logs

There are no logs, which adds to the confusion.
The request fails silently, and sessionToken() returns an empty string.

Flutter Doctor output

Doctor output
✓] Flutter (Channel stable, 3.27.1, on macOS 14.6.1 23G93 darwin-arm64, locale en-RO)
    • Flutter version 3.27.1 on channel stable at /Users/rolandtolnay/fvm/versions/3.27.1
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 17025dd882 (4 weeks ago), 2024-12-17 03:23:09 +0900
    • Engine revision cb4b5fff73
    • Dart version 3.6.0
    • DevTools version 2.40.2

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
    • Android SDK at /Users/rolandtolnay/Library/Android/sdk
    • Platform android-35, build-tools 33.0.1
    • ANDROID_HOME = /Users/rolandtolnay/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)

[✓] VS Code (version 1.96.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.102.0

[✓] Connected device (5 available)
    • iPhone 15 (mobile)              • 1B410364-FD4D-4B67-8549-D177C91C6EB7 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-17-5 (simulator)
    • macOS (desktop)                 • macos                                • darwin-arm64   • macOS 14.6.1 23G93 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                • darwin         • macOS 14.6.1 23G93 darwin-arm64
    • Chrome (web)                    • chrome                               • web-javascript • Google Chrome 131.0.6778.265

[✓] Network resources
    • All expected network resources are available.
@2math
Copy link

2math commented Jan 29, 2025

I just faced the same problem(I haven't tested my app after the login was successful).
It looks like no headers are set with POST on this endpoint '/client/sessions/${_tokenCache.sessionId}/tokens'
I have local copy on my side and after passed headers on _updateSessionToken() is working OK

final resp = await _fetch(
        path: '/client/sessions/${_tokenCache.sessionId}/tokens',
        headers: _headers(HttpMethod.post),
      );

If you use ClerkAuth widget, you may want to pass SessionTokenPollMode.regular as will try with a timer to refresh the token on each 55 seconds(the token seems to live 60s). In general if the app is in background and not in debug mode this timer will be blocked by the OS and you should always rely on manually refresh the token when get 401 from your server.

ClerkAuth(
              pollMode: SessionTokenPollMode.regular,
              ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working clerk_auth package: clerk_auth
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants