Flutter SDK
The auth_gate_flutter package brings AuthGate authentication to Flutter apps. OAuth flows open the system browser and return via deep link, tokens are stored in secure storage, and session restore happens automatically on app launch.
Installation
Add to your pubspec.yaml:
dependencies:
auth_gate_flutter: ^0.6.0
Or install via CLI:
flutter pub add auth_gate_flutter
Dependencies http, flutter_secure_storage, url_launcher, and app_links are included automatically.
Deep link setup
The SDK uses deep links to receive OAuth callbacks. Configure your app's URL scheme for each platform.
Android
Add to android/app/src/main/AndroidManifest.xml inside the <activity> tag:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" android:host="auth" />
</intent-filter>
iOS
Add to ios/Runner/Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
Then register the callback URL in the AuthGate dashboard:
myapp://auth/callback
Navigate to Dashboard → Callback URLs and add the URL above.
Setup
1. Wrap your app with AuthGateProvider
lib/main.dart
import 'package:auth_gate_flutter/auth_gate_flutter.dart';
void main() {
runApp(
AuthGateProvider(
config: AuthGateConfig(
apiKey: 'ag_...',
baseUrl: 'https://www.authgate.dev',
scheme: 'myapp',
),
child: const MyApp(),
),
);
}
2. Access auth state
lib/screens/profile.dart
import 'package:auth_gate_flutter/auth_gate_flutter.dart';
class ProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = AuthGateProvider.of(context);
if (auth.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (!auth.isAuthenticated) {
return const LoginPage();
}
return Center(
child: Column(
children: [
Text('Hello, ${auth.user!.name}'),
ElevatedButton(
onPressed: auth.logout,
child: const Text('Sign out'),
),
],
),
);
}
}
Authentication
OAuth
Opens the system browser for the OAuth flow. The SDK handles the deep link callback and token storage automatically.
final auth = AuthGateProvider.of(context);
await auth.loginWithOAuth(OAuthProvider.google);
await auth.loginWithOAuth(OAuthProvider.github);
await auth.loginWithOAuth(OAuthProvider.discord);
await auth.loginWithOAuth(OAuthProvider.azure);
await auth.loginWithOAuth(OAuthProvider.apple);
final auth = AuthGateProvider.of(context);
// Sign up (with optional locale)
await auth.client.emailSignup(
email: 'alice@example.com',
password: 'password123',
name: 'Alice',
locale: 'it', // Optional
);
// Sign in (with optional locale)
final response = await auth.loginWithEmail(
'alice@example.com',
'password123',
locale: 'it', // Optional
);
if (response.mfaRequired) {
// MFA challenge — prompt user for code
await auth.verifyMfa(
response.mfaChallenge!,
totpCode,
MfaMethod.totp,
);
}
Magic link
await auth.client.magicLinkSend(
email: 'alice@example.com',
callbackUrl: 'myapp://auth/callback',
);
// User receives an email with a link that opens the app
SMS
// Send verification code
await auth.client.smsSendCode(phone: '+15551234567');
// Verify and sign in
await auth.loginWithSms('+15551234567', '123456');
Route protection
Use the AuthGate widget for conditional rendering based on auth state:
import 'package:auth_gate_flutter/auth_gate_flutter.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AuthGate(
authenticated: const DashboardScreen(),
unauthenticated: const LoginScreen(),
loading: const Center(child: CircularProgressIndicator()),
);
}
}
| Parameter | Type | Description |
|---|---|---|
authenticated | Widget | Shown when user is signed in |
unauthenticated | Widget | Shown when user is not signed in |
loading | Widget? | Shown while session is restoring (defaults to empty) |
Configuration
- Name
apiKey- Type
- String
- Description
Your AuthGate API key.
- Name
baseUrl- Type
- String
- Description
URL of your AuthGate instance.
- Name
scheme- Type
- String
- Description
Deep link scheme for OAuth callbacks (e.g.
"myapp").
- Name
sessionMaxAge- Type
- int
- Description
Session lifetime in seconds (default: 7 days).
- Name
callbackPath- Type
- String
- Description
Deep link callback path fragment.
API reference
AuthGateProvider
Widget that provides AuthNotifier to the widget tree via InheritedNotifier.
final auth = AuthGateProvider.of(context);
AuthNotifier
| Property / Method | Type | Description |
|---|---|---|
user | AuthGateUser? | Current user or null |
isLoading | bool | True while restoring session on launch |
isAuthenticated | bool | Whether a user is signed in |
client | AuthGateClient | Low-level HTTP client for advanced usage |
loginWithOAuth(provider) | Future<void> | Start OAuth flow in system browser |
loginWithEmail(email, password) | Future<AuthResponse> | Email sign-in (may return MFA challenge) |
loginWithSms(phone, code) | Future<void> | Verify SMS code and sign in |
verifyMfa(challenge, code, method) | Future<void> | Complete MFA challenge |
logout() | Future<void> | Sign out and clear secure storage |
AuthGateUser
class AuthGateUser {
String id; // Unique user ID
String? email; // Email (null for SMS-only users)
String? phone; // Phone in E.164 format
String? name; // Display name
String? picture; // Avatar URL
String provider; // Auth provider used
}
OAuthProvider
enum OAuthProvider { google, github, discord, azure, apple }
How sessions work
- Tokens are stored in flutter_secure_storage (Keychain on iOS, EncryptedSharedPreferences on Android)
- On app launch, the stored token is verified server-side
- If the token is expired, the refresh token is used automatically
- Token refresh is scheduled before expiry to maintain seamless sessions