Getting Started

Quick Start

Add authentication to your Dart or Flutter project in under 5 minutes.

Pick your path:


Flutter app

1. Install

pubspec.yaml
dependencies:
  authyra_flutter: ^0.1.0
flutter pub get

2. Initialize at startup

lib/main.dart
import 'package:authyra_flutter/authyra_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Authyra.initialize(
    client: AuthyraClient(
      providers: [
        CredentialsProvider.withTokens(
          id: 'email',
          authorize: (creds) async {
            final res = await myApi.post('/auth/login', body: creds);
            if (res.statusCode != 200) return null;
            return AuthSignInResult(
              user: AuthUser(id: res.data['id'], email: res.data['email']),
              accessToken:  res.data['accessToken'],
              refreshToken: res.data['refreshToken'],
              expiresAt:    DateTime.parse(res.data['expiresAt']),
            );
          },
        ),
        GoogleProvider(clientId: 'YOUR_GOOGLE_CLIENT_ID'),
      ],
      storage: SecureAuthStorage(), // Keychain on iOS, Keystore on Android
    ),
  );

  runApp(const MyApp());
}
SecureAuthStorage is provided by authyra_flutter. For OAuth2 providers, wire OAuth2CallbackHandler with your deep-link package — see Flutter Setup →.

3. Sign in

// Email / password
final user = await Authyra.instance.signIn('email', params: {
  'email':    'alice@example.com',
  'password': 's3cr3t',
});

// Google — launches browser, waits for deep-link callback
final user = await Authyra.instance.signIn('google');

4. React to auth state

StreamBuilder<AuthState>(
  stream: Authyra.instance.authStateChanges,
  builder: (context, snapshot) {
    final state = snapshot.data ?? AuthState.unauthenticated();
    return switch (state.type) {
      AuthStateType.authenticated   => HomePage(user: state.user!),
      AuthStateType.unauthenticated => LoginPage(),
      AuthStateType.error           => ErrorPage(state.error!),
    };
  },
);

Or read synchronously (safe in build() — no awaiting):

if (Authyra.instance.isAuthenticated) {
  print('Hello, ${Authyra.instance.currentUser!.name}');
}

5. Sign out

await Authyra.instance.signOut();
// authStateChanges emits AuthState.unauthenticated()

Dart backend

Add the package

pubspec.yaml
dependencies:
  authyra: ^0.1.0
dart pub get

2. Build and initialize the client

bin/server.dart
import 'package:authyra/authyra.dart';

void main() async {
  final client = AuthyraClient(
    providers: [
      CredentialsProvider.withTokens(
        id: 'email',
        authorize: (creds) async {
          final res = await myApi.post('/auth/login', body: creds);
          if (res.statusCode != 200) return null;
          return AuthSignInResult(
            user: AuthUser(id: res.data['id'], email: res.data['email']),
            accessToken:  res.data['accessToken'],
            refreshToken: res.data['refreshToken'],
            expiresAt:    DateTime.parse(res.data['expiresAt']),
          );
        },
      ),
    ],
    storage: MyRedisStorage(), // implement AuthStorage for your backend
  );

  await client.initialize();
}

3. Authenticate

final user = await client.signIn('email', params: {
  'email':    'alice@example.com',
  'password': 's3cr3t',
});
print('Signed in: ${user.email}');

4. React to state changes

client.authStateStream.listen((AuthState state) {
  switch (state.type) {
    case AuthStateType.authenticated:
      print('Signed in as ${state.user!.email}');
    case AuthStateType.unauthenticated:
      print('Signed out');
    case AuthStateType.error:
      print('Error: ${state.error}');
  }
});

5. Sign out the client

await client.signOut();

Full example — pure Dart

bin/main.dart
import 'package:authyra/authyra.dart';

Future<void> main() async {
  final client = AuthyraClient(
    providers: [
      CredentialsProvider(
        id: 'email',
        authorize: (creds) async {
          if (creds?['password'] == 'secret') {
            return AuthUser(id: '1', email: creds!['email'] as String);
          }
          return null;
        },
      ),
    ],
    storage: InMemoryStorage(),
  );

  await Authyra.initialize(client: client);

  Authyra.instance.authStateChanges.listen((state) {
    print('[auth] ${state.type.name}');
  });

  try {
    final user = await Authyra.instance.signIn('email', params: {
      'email':    'alice@example.com',
      'password': 'secret',
    });
    print('Signed in: ${user.email}');
  } on AuthenticationFailedException catch (e) {
    print('Wrong credentials: $e');
  }

  final session = await Authyra.instance.getSession();
  print('Token: ${session?.accessToken}');

  await Authyra.instance.signOut();
  print('isAuthenticated: ${Authyra.instance.isAuthenticated}'); // false

  await Authyra.instance.dispose();
}

What's next?

Architecture

How AuthyraClient, AuthyraInstance, and SessionManager fit together.

Flutter Setup

Wire OAuth2 callbacks, configure SecureAuthStorage, integrate GoRouter.

Credentials Provider

Email / password in depth — basic and .withTokens variants.
Copyright © 2026