Authentication flows
Learn how to handle sign-in, sign-up, MFA, password reset, and session management with the Clerk Flutter SDK.
The Flutter SDK provides pre-built widgets that handle authentication flows automatically, as well as a lower-level API for building custom UI.
Pre-built authentication UI
The ClerkAuthentication widget handles sign-in and sign-up flows, including OAuth, MFA, and password reset, with no additional code required.
ClerkAuthentication()Place it anywhere in your widget tree when the user is signed out. Wrap your app with ClerkAuth to provide the auth state.
ClerkAuth(
config: ClerkAuthConfig(publishableKey: 'pk_...'),
child: ClerkAuthBuilder(
signedInBuilder: (context, auth) => const HomeScreen(),
signedOutBuilder: (context, auth) => const ClerkAuthentication(),
),
)For custom UI, access the auth state with ClerkAuth.of(context) and use the methods below.
Sign in
The attemptSignIn method is progressive — call it repeatedly with updated parameters as the user moves through each step of the flow.
Sign in with password
The following example demonstrates how to sign in with an identifier (email, phone, or username) and password.
final auth = ClerkAuth.of(context);
await auth.attemptSignIn(
strategy: Strategy.password,
identifier: 'user@email.com',
password: 'secretpassword',
);Sign in with OTP (email)
The following example demonstrates how to send an OTP to the user's email and verify the code.
final auth = ClerkAuth.of(context);
// Send the code
await auth.attemptSignIn(
strategy: Strategy.emailCode,
identifier: 'user@email.com',
);
// Verify the code
await auth.attemptSignIn(
strategy: Strategy.emailCode,
code: '123456',
);Sign in with OTP (phone)
The following example demonstrates how to send an OTP to the user's phone number and verify the code.
final auth = ClerkAuth.of(context);
// Send the code
await auth.attemptSignIn(
strategy: Strategy.phoneCode,
identifier: '+1234567890',
);
// Verify the code
await auth.attemptSignIn(
strategy: Strategy.phoneCode,
code: '123456',
);Sign in with email link
The following example demonstrates how to send a magic link to the user's email. The link will be polled automatically.
final auth = ClerkAuth.of(context);
await auth.attemptSignIn(
strategy: Strategy.emailLink,
identifier: 'user@email.com',
redirectUrl: 'yourapp://clerk/callback',
);Sign in with OAuth
The following example demonstrates how to sign in using an OAuth provider (e.g., Google, GitHub).
final auth = ClerkAuth.of(context);
await auth.ssoSignIn(context, Strategy.oauthGoogle);The SDK handles the OAuth redirect flow in-app using a WebView by default. To handle the redirect externally (e.g., via a deep link), configure a redirectionGenerator in ClerkAuthConfig.
Sign in with ID token
The following example demonstrates how to sign in with an ID token from an identity provider (e.g., Apple).
final auth = ClerkAuth.of(context);
await auth.idTokenSignIn(
provider: IdTokenProvider.apple,
token: credential.identityToken,
);
// If the user doesn't exist, transfer to sign-up
if (auth.signIn?.isTransferable == true) {
await auth.transfer();
}Sign in with passkey
The following example demonstrates how to sign in using a passkey.
final auth = ClerkAuth.of(context);
await auth.attemptSignIn(strategy: Strategy.passkey);Sign in with Enterprise SSO
The following example demonstrates how to sign in using Enterprise SSO.
final auth = ClerkAuth.of(context);
await auth.ssoSignIn(context, Strategy.enterpriseSSO);Multi-factor authentication
After the first factor is verified, if MFA is required, call attemptSignIn again with the second factor strategy.
MFA with phone code
The following example demonstrates how to send an SMS code and verify it as the second factor.
// Send the SMS code
await auth.attemptSignIn(strategy: Strategy.phoneCode);
// Verify the code
await auth.attemptSignIn(
strategy: Strategy.phoneCode,
code: '123456',
);MFA with email code
The following example demonstrates how to send an email code and verify it as the second factor.
// Send the email code
await auth.attemptSignIn(strategy: Strategy.emailCode);
// Verify the code
await auth.attemptSignIn(
strategy: Strategy.emailCode,
code: '123456',
);MFA with TOTP (authenticator app)
The following example demonstrates how to verify the TOTP code from the user's authenticator app.
await auth.attemptSignIn(
strategy: Strategy.totp,
code: '123456',
);MFA with backup code
The following example demonstrates how to sign in using one of the user's backup codes.
await auth.attemptSignIn(
strategy: Strategy.backupCode,
code: 'backup-code',
);Resend a code
The following example demonstrates how to resend the OTP or sign-in code for the current strategy.
await auth.resendCode(Strategy.phoneCode);Password reset
Password reset with email
The following example demonstrates how to send a reset code to the user's email, verify it, and set the new password.
final auth = ClerkAuth.of(context);
// Initiate reset and send code
await auth.initiatePasswordReset(
identifier: 'user@email.com',
strategy: Strategy.resetPasswordEmailCode,
);
// Verify the code and set the new password
await auth.attemptSignIn(
strategy: Strategy.resetPasswordEmailCode,
code: '123456',
password: 'newpassword',
);Password reset with phone
The following example demonstrates how to send a reset code to the user's phone number, verify it, and set the new password.
final auth = ClerkAuth.of(context);
// Initiate reset and send code
await auth.initiatePasswordReset(
identifier: '+1234567890',
strategy: Strategy.resetPasswordPhoneCode,
);
// Verify the code and set the new password
await auth.attemptSignIn(
strategy: Strategy.resetPasswordPhoneCode,
code: '123456',
password: 'newpassword',
);Sign up
The attemptSignUp method is progressive — call it repeatedly with updated parameters until the user is fully signed up.
Create a new sign-up
The following example demonstrates how to start a sign-up. Only include fields required by your instance configuration.
final auth = ClerkAuth.of(context);
await auth.attemptSignUp(
emailAddress: 'newuser@email.com',
password: 'secretpassword',
firstName: 'John',
lastName: 'Doe',
username: 'johndoe',
phoneNumber: '+1234567890',
);Verify email via OTP
The following example demonstrates how to verify an email address after sign-up using an OTP code.
// Send the verification code (triggered automatically by attemptSignUp,
// or call again with the emailCode strategy)
await auth.attemptSignUp(strategy: Strategy.emailCode);
// Verify the code
await auth.attemptSignUp(
strategy: Strategy.emailCode,
code: '123456',
);Verify phone via OTP
The following example demonstrates how to send a verification code to the user's phone number and verify it.
// Send the verification code
await auth.attemptSignUp(strategy: Strategy.phoneCode);
// Verify the code
await auth.attemptSignUp(
strategy: Strategy.phoneCode,
code: '123456',
);Sign up with OAuth
The following example demonstrates how to sign up using an OAuth provider (e.g., Google, GitHub).
final auth = ClerkAuth.of(context);
await auth.ssoSignUp(context, Strategy.oauthGoogle);Sign up with ID token
The following example demonstrates how to sign up with an ID token from an identity provider (e.g., Apple).
final auth = ClerkAuth.of(context);
await auth.idTokenSignUp(
provider: IdTokenProvider.apple,
idToken: credential.identityToken!,
firstName: credential.givenName,
lastName: credential.familyName,
);
// If the user already exists, transfer to sign-in
if (auth.signUp?.isTransferable == true) {
await auth.transfer();
}Sign up with Enterprise SSO
The following example demonstrates how to sign up using Enterprise SSO.
final auth = ClerkAuth.of(context);
await auth.ssoSignUp(context, Strategy.enterpriseSSO);Current sign-in/sign-up
Access the in-progress sign-in or sign-up for multi-step flows.
Current sign-in
The following example demonstrates how to access the in-progress sign-in object.
final signIn = ClerkAuth.of(context).signIn;Current sign-up
The following example demonstrates how to access the in-progress sign-up object.
final signUp = ClerkAuth.of(context).signUp;Session management
Sessions
The following example demonstrates how to retrieve all sessions for the current client.
final sessions = ClerkAuth.of(context).client.sessions;Get session token
The following example demonstrates how to retrieve the current session token to authenticate requests to your backend.
final auth = ClerkAuth.of(context);
final tokenObj = await auth.sessionToken();
final token = tokenObj.jwt;You can also listen to the sessionTokenStream for token renewals.
auth.sessionTokenStream.listen((token) {
// Use token.jwt to authenticate requests
});Set active session
The following example demonstrates how to switch to a different session.
final auth = ClerkAuth.of(context);
final session = auth.client.sessions.firstOrNull;
if (session == null) return;
await auth.activate(session);Set active organization
The following example demonstrates how to set the active organization for the current session.
final auth = ClerkAuth.of(context);
final organization = auth.user?.organizationMemberships?.firstOrNull?.organization;
if (organization == null) return;
await auth.setActiveOrganization(organization);Sign out
The following example demonstrates how to sign out the current user from all sessions, or from a specific session.
final auth = ClerkAuth.of(context);
// Sign out from all sessions
await auth.signOut();
// Sign out from a specific session
final session = auth.session;
await auth.signOutOf(session!);