vestibule_auth 0.0.1-beta.1
vestibule_auth: ^0.0.1-beta.1 copied to clipboard
Multi-tenant OTP authentication client for Vestibule
Vestibule Auth #
A Flutter authentication client for Vestibule, providing secure multi-tenant OTP and social sign-in capabilities.
Features #
- Email OTP Authentication - Send and verify one-time passwords via email
- SMS OTP Authentication - Send and verify one-time passwords via SMS
- Multi-Factor Authentication - Chain multiple authentication factors (e.g., email + phone)
- Social Sign-In - Authenticate with Google and Apple
- Device Fingerprinting - Automatic device identification for security
- Secure Token Management - JWT and refresh token handling with automatic storage
- Multi-Tenant Support - Isolated authentication per tenant ID
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
vestibule_auth: ^0.0.1
Then run:
flutter pub get
Usage #
Initialize the Client #
import 'package:vestibule_auth/client.dart';
final authClient = VestibuleClient(
serverUrl: 'https://your-vestibule-server.com',
tenantId: 'your-tenant-id',
);
Email OTP Authentication #
// Request OTP
final requestResult = await authClient.requestOTP(
recipient: 'user@example.com',
deliveryMethod: DeliveryMethod.DELIVERY_METHOD_EMAIL,
);
// Verify OTP
final verifyResult = await authClient.verifyOTP(
recipient: 'user@example.com',
code: '123456',
);
if (verifyResult.hasJwt()) {
final jwt = verifyResult.jwt;
final refreshToken = verifyResult.refreshToken;
// User is authenticated
}
SMS OTP Authentication #
// Request OTP
final requestResult = await authClient.requestOTP(
recipient: '+1234567890',
deliveryMethod: DeliveryMethod.DELIVERY_METHOD_SMS,
);
// Verify OTP
final verifyResult = await authClient.verifyOTP(
recipient: '+1234567890',
code: '123456',
);
Multi-Factor Authentication #
Vestibule supports chaining multiple authentication factors:
// Step 1: Verify email (first factor)
final emailResult = await authClient.verifyOTP(
recipient: 'user@example.com',
code: '123456',
);
String? verifyToken;
if (emailResult.hasVerifyToken()) {
verifyToken = emailResult.verifyToken;
// First factor verified, need second factor
}
// Step 2: Request phone OTP (second factor)
await authClient.requestOTP(
recipient: '+1234567890',
deliveryMethod: DeliveryMethod.DELIVERY_METHOD_SMS,
);
// Step 3: Verify phone with verify token
final phoneResult = await authClient.verifyOTP(
recipient: '+1234567890',
code: '654321',
verifyToken: verifyToken,
);
if (phoneResult.hasJwt()) {
// User is fully authenticated
}
Social Sign-In #
Google Sign-In
final result = await authClient.signInWithGoogle();
if (result.hasJwt()) {
// User is authenticated
} else if (result.hasVerifyToken()) {
// Additional factor required (e.g., phone verification)
}
Apple Sign-In
final result = await authClient.signInWithApple();
if (result.hasJwt()) {
// User is authenticated
} else if (result.hasVerifyToken()) {
// Additional factor required (e.g., phone verification)
}
Token Management #
The client provides secure token storage using flutter_secure_storage:
// Save tokens after authentication
final verifyResult = await authClient.verifyOTP(
recipient: 'user@example.com',
code: '123456',
);
if (verifyResult.hasJwt() && verifyResult.hasRefreshToken()) {
await authClient.saveTokens(
jwt: verifyResult.jwt,
refreshToken: verifyResult.refreshToken,
);
}
// Get stored JWT
final jwt = await authClient.getStoredJWT();
// Get stored refresh token
final refreshToken = await authClient.getStoredRefreshToken();
// Refresh stored token automatically
final success = await authClient.refreshStoredToken();
if (success) {
// Token refreshed and saved automatically
final newJwt = await authClient.getStoredJWT();
}
// Clear stored tokens (logout)
await authClient.clearTokens();
Automatic Token Storage
Enable automatic token storage to save tokens after successful authentication:
final authClient = VestibuleClient(
serverUrl: 'https://your-vestibule-server.com',
tenantId: 'your-tenant-id',
autoSaveTokens: true, // Automatically save tokens after authentication
);
// Tokens are automatically saved after successful authentication
final result = await authClient.verifyOTP(
recipient: 'user@example.com',
code: '123456',
);
// No need to manually call saveTokens()
Manual Token Storage
For more control over token persistence, disable automatic storage:
final authClient = VestibuleClient(
serverUrl: 'https://your-vestibule-server.com',
tenantId: 'your-tenant-id',
// autoSaveTokens defaults to false
);
// Manually save tokens when needed
final result = await authClient.verifyOTP(
recipient: 'user@example.com',
code: '123456',
);
if (result.hasJwt() && result.hasRefreshToken()) {
await authClient.saveTokens(
jwt: result.jwt,
refreshToken: result.refreshToken,
);
}
Device Information #
The client automatically collects device information for security purposes:
final deviceInfo = await authClient.getDeviceInfo();
// Returns: DeviceInfo with device ID, OS, model, etc.
Configuration #
Android Setup #
For Google Sign-In on Android, add your OAuth client ID to android/app/src/main/res/values/strings.xml:
<string name="default_web_client_id">YOUR_WEB_CLIENT_ID</string>
iOS Setup #
For Apple Sign-In on iOS, enable the "Sign in with Apple" capability in Xcode.
For Google Sign-In on iOS, add your reversed client ID to Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_REVERSED_CLIENT_ID</string>
</array>
</dict>
</array>
API Reference #
VestibuleClient #
Constructor
VestibuleClient({
required String serverUrl,
required String tenantId,
Transport? transport,
GoogleSignIn? googleSignIn,
FlutterSecureStorage? secureStorage,
bool autoSaveTokens = false,
})
Parameters:
serverUrl- Your Vestibule server URLtenantId- Your tenant IDtransport- Optional custom transport (for testing)googleSignIn- Optional GoogleSignIn instance (required for Google auth)secureStorage- Optional custom secure storage (for testing)autoSaveTokens- Whentrue, automatically saves tokens after successful authentication. Default:false
Methods
Authentication
requestOTP({required String recipient, required DeliveryMethod deliveryMethod})- Request an OTP codeverifyOTP({required String recipient, required String code, String? verifyToken})- Verify an OTP codesignInWithGoogle()- Authenticate with GooglesignInWithApple()- Authenticate with Apple
Token Management
saveTokens({required String jwt, required String refreshToken})- Store tokens in secure storagegetStoredJWT()- Get stored JWT tokengetStoredRefreshToken()- Get stored refresh tokenrefreshToken({required String refreshToken})- Refresh a JWT using a refresh tokenrefreshStoredToken()- Refresh and save the stored JWT automaticallyclearTokens()- Clear stored tokens from secure storage
Utilities
getPublicKey()- Get tenant's public key for JWT verificationgetDeviceInfo()- Get device information
Response Types #
All authentication methods return a response with:
jwt- JWT access token (if authentication is complete)refreshToken- Refresh token (if authentication is complete)verifyToken- Verification token (if additional factors are required)message- Response message
Example #
See the example directory for a complete Flutter app demonstrating all authentication methods.
License #
See LICENSE file for details.