VooStackAuth Client
A comprehensive Flutter SDK for VooStackAuth - a centralized authentication platform. Supports email/password authentication, OAuth providers, automatic token refresh, and provider linking.
Features
- Email/Password Authentication - Register and login with email and password
- OAuth Providers - Login with Google, GitHub, Microsoft, Apple, Discord
- Token Management - Automatic token storage and refresh
- Provider Linking - Link/unlink multiple OAuth providers to a single account
- Dio Interceptor - Automatic token refresh with request queuing
- Type Safe - Fully typed with strong type constraints
- Clean Architecture - Following best practices with VooCore integration
Installation
Add to your pubspec.yaml:
dependencies:
voostackauth_client: ^0.1.0
Or for local development in the VooFlutter monorepo:
dependencies:
voostackauth_client:
path: packages/dev/voostackauth_client
Quick Start
1. Initialize the Service
import 'package:voostackauth_client/voostackauth_client.dart';
final authService = VooStackAuthService(
config: VooStackAuthConfig(
baseUrl: 'https://auth.voostack.com/api',
),
);
// Initialize (checks for stored tokens)
await authService.initialize();
2. Register a New User
try {
final result = await authService.register(
email: 'user@example.com',
password: 'securePassword123',
firstName: 'John',
lastName: 'Doe',
);
print('Welcome, ${result.user.fullName}!');
} on VooStackAuthException catch (e) {
print('Registration failed: ${e.message}');
}
3. Login with Email/Password
try {
final result = await authService.loginWithEmail(
email: 'user@example.com',
password: 'securePassword123',
);
print('Logged in as ${result.user.email}');
} on VooStackAuthException catch (e) {
if (e.code == 'invalid-credentials') {
print('Invalid email or password');
}
}
4. Login with OAuth Provider
// With access token from OAuth provider
final result = await authService.loginWithOAuthToken(
provider: OAuthProvider.google,
token: googleAccessToken,
);
// With authorization code
final result = await authService.loginWithOAuthCode(
provider: OAuthProvider.github,
code: authorizationCode,
redirectUri: 'https://yourapp.com/callback',
);
5. Listen to Auth State Changes
authService.statusStream.listen((status) {
switch (status) {
case AuthStatus.authenticated:
print('User is logged in');
break;
case AuthStatus.unauthenticated:
print('User is logged out');
break;
case AuthStatus.authenticating:
print('Login in progress...');
break;
case AuthStatus.refreshing:
print('Refreshing token...');
break;
case AuthStatus.error:
print('Authentication error');
break;
}
});
authService.userStream.listen((user) {
if (user != null) {
print('Current user: ${user.fullName}');
}
});
OAuth Providers
Supported OAuth providers:
| Provider | Enum Value |
|---|---|
OAuthProvider.google |
|
| GitHub | OAuthProvider.github |
| Microsoft | OAuthProvider.microsoft |
| Apple | OAuthProvider.apple |
| Discord | OAuthProvider.discord |
Provider Linking
Link multiple OAuth providers to a single account:
// Get linked providers
final providers = await authService.getLinkedProviders();
for (final provider in providers) {
print('${provider.providerType}: ${provider.email}');
}
// Link a new provider
final linked = await authService.linkProviderWithToken(
provider: OAuthProvider.github,
token: githubAccessToken,
);
print('Linked ${linked.providerType}');
// Unlink a provider
await authService.unlinkProvider(OAuthProvider.github);
Token Management
Custom Token Storage
Implement TokenStorage for persistent storage:
class SecureTokenStorage implements TokenStorage {
final FlutterSecureStorage _storage = FlutterSecureStorage();
@override
Future<void> saveTokens(AuthTokens tokens) async {
await _storage.write(key: 'auth_tokens', value: jsonEncode(tokens.toJson()));
}
@override
Future<AuthTokens?> getTokens() async {
final data = await _storage.read(key: 'auth_tokens');
if (data == null) return null;
return AuthTokens.fromJson(jsonDecode(data));
}
@override
Future<void> deleteTokens() async {
await _storage.delete(key: 'auth_tokens');
}
@override
Future<bool> hasTokens() async {
return await _storage.containsKey(key: 'auth_tokens');
}
}
// Use custom storage
final authService = VooStackAuthService(
config: VooStackAuthConfig(baseUrl: 'https://auth.voostack.com/api'),
tokenStorage: SecureTokenStorage(),
);
Auto-Refresh Interceptor
Add the interceptor to your Dio instance for automatic token refresh:
final dio = Dio();
dio.interceptors.add(AuthInterceptor(
authService: authService,
refreshBuffer: Duration(minutes: 5), // Refresh 5 min before expiry
));
// All requests will now automatically include auth headers
// and refresh tokens when needed
final response = await dio.get('/api/protected-resource');
Configuration
VooStackAuthConfig(
// Required
baseUrl: 'https://auth.voostack.com/api',
// Optional
connectTimeout: Duration(seconds: 30),
receiveTimeout: Duration(seconds: 30),
autoRefreshBuffer: Duration(minutes: 5),
)
Error Handling
All auth errors throw VooStackAuthException:
try {
await authService.loginWithEmail(email: email, password: password);
} on VooStackAuthException catch (e) {
switch (e.code) {
case 'invalid-credentials':
// Wrong email or password
break;
case 'unauthenticated':
// User not logged in
break;
case 'token-expired':
// Token has expired
break;
case 'refresh-failed':
// Failed to refresh token
break;
case 'network-error':
// Network connectivity issue
break;
case 'email-in-use':
// Email already registered
break;
case 'provider-already-linked':
// OAuth provider already linked
break;
case 'provider-not-linked':
// OAuth provider not linked
break;
default:
print('Error: ${e.message}');
}
}
API Reference
VooStackAuthService
| Method | Description |
|---|---|
initialize() |
Check for stored tokens and restore session |
register() |
Register new user with email/password |
loginWithEmail() |
Login with email and password |
loginWithOAuthToken() |
Login with OAuth provider token |
loginWithOAuthCode() |
Login with OAuth authorization code |
refreshToken() |
Manually refresh the access token |
logout() |
Logout and clear tokens |
getCurrentUser() |
Fetch current user info |
getLinkedProviders() |
Get all linked OAuth providers |
linkProviderWithToken() |
Link OAuth provider with token |
linkProviderWithCode() |
Link OAuth provider with code |
unlinkProvider() |
Unlink an OAuth provider |
dispose() |
Clean up resources |
Properties
| Property | Type | Description |
|---|---|---|
status |
AuthStatus |
Current auth status |
currentUser |
UserInfo? |
Current user info |
currentTokens |
AuthTokens? |
Current tokens |
isAuthenticated |
bool |
Whether user is authenticated |
statusStream |
Stream<AuthStatus> |
Auth status changes |
userStream |
Stream<UserInfo?> |
User changes |
authenticatedDio |
Dio |
Dio instance with auth headers |
Example
See the example folder for a complete sample application demonstrating:
- Email/password registration and login
- OAuth provider authentication
- Auth state management
- Provider linking/unlinking
- Token refresh
Run the example:
cd example
flutter run -d chrome
Architecture
lib/
├── voostackauth_client.dart # Main export
└── src/
├── enums/
│ ├── auth_status.dart # Authentication states
│ └── oauth_provider.dart # OAuth provider enum
├── exceptions/
│ └── voostackauth_exception.dart
├── interceptors/
│ └── auth_interceptor.dart # Auto-refresh interceptor
├── models/
│ ├── auth_result.dart # Login/register result
│ ├── auth_tokens.dart # JWT tokens
│ ├── linked_provider.dart # Linked OAuth provider
│ └── user_info.dart # User information
└── services/
├── auth_service.dart # Main auth service
└── token_storage.dart # Token storage interface
Learn More
License
MIT License - see LICENSE for details.
Built by VooStack
Need help with Flutter development or authentication solutions?
VooStack builds enterprise Flutter applications and developer tools. We're here to help with your next project.
Libraries
- voostackauth_client
- Flutter SDK for VooStackAuth - a centralized authentication platform.