Getting Started
Quick Start
Add authentication to your Dart or Flutter project in under 5 minutes.
Pick your path:
- Flutter app — email/password + optional OAuth2 (Google, GitHub…)
- Pure Dart / backend — Shelf, Dart Frog, CLI
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();
}