ajolote 0.2.1
ajolote: ^0.2.1 copied to clipboard
Cliente Flutter para el servicio de autenticación centralizado de Anfibia/4Quinas. Multi-tenant, JWT, OTP por SMS, biometría.
Ajolote #
Flutter client for Ajolote, an authentication server with multi-tenant isolation, JWT-based sessions, and built-in support for OTP, biometrics, and social login.
Why Ajolote? #
Most auth SDKs assume one app, one tenant, and tightly couple your frontend to a specific vendor. Ajolote is built for organizations that:
- Run multiple apps that share users but isolate data per product
- Need OTP-by-SMS, social login, and biometric unlock without stitching three vendors together
- Want to own the auth server (it's open source) instead of paying per MAU
You run the server, this package talks to it.
Features #
- 🔐 Email + password authentication
- 📱 SMS OTP via the Ajolote server
- 🌐 Social OAuth (Google) with deep links and CSRF state validation
- 🔁 Automatic access token refresh with concurrent-request deduplication
- 🛡️ Secure token storage in Keychain/Keystore (via
flutter_secure_storage) - 👆 Optional biometric unlock (via
local_auth) - 🔄 Reactive via
ChangeNotifier— works with any state management - 🌐 Server-to-server client for Dart backends (Shelf, Dart Frog)
- 🎯 Multi-tenant by design — each app is an isolated tenant
Installation #
Add ajolote to your pubspec.yaml:
```yaml dependencies: flutter: sdk: flutter ajolote: ^0.2.1
Optional, depending on which features you use: #
local_auth: ^2.3.0 # for biometric unlock app_links: ^6.3.0 # for social OAuth url_launcher: ^6.3.0 # for social OAuth ```
Then run:
bash flutter pub get
Quickstart #
```dart import 'package:flutter/material.dart'; import 'package:ajolote/ajolote.dart';
void main() async { WidgetsFlutterBinding.ensureInitialized();
final auth = AjoloteClient( appId: 'my-app', baseUrl: Uri.parse('https://auth.example.com'), );
await auth.init(); // restores previous session if any
runApp(MyApp(auth: auth)); } ```
Sign in with email and password #
```dart await auth.signInWithEmail( email: 'user@example.com', password: 'secret', );
// auth.session now has the user and tokens final user = auth.session?.user; ```
Get a valid access token for your API calls #
```dart final token = await auth.getValidToken();
final response = await http.get( Uri.parse('https://your-api.example.com/resource'), headers: {'Authorization': 'Bearer $token'}, ); ```
The client automatically refreshes the access token when it's near expiration, deduplicating concurrent refresh requests.
Reactive UI with ChangeNotifier #
dart ListenableBuilder( listenable: auth, builder: (context, _) { if (auth.session == null) return const LoginScreen(); return HomeScreen(user: auth.session!.user); }, )
Works with Provider, Riverpod, BLoC, or any state management that supports Listenable.
Sign out #
dart await auth.signOut();
Advanced features #
See the example app for complete implementations of:
- SMS OTP flow (
PhoneAuth) - Google OAuth with deep links (
SocialAuth) - Biometric unlock (
Biometric) - Server-to-server token validation (
AjoloteServerClient)
The Ajolote server #
This package is a client. You need an Ajolote server running to use it. The server handles user storage, token issuance, OTP delivery, OAuth flows, and multi-tenant isolation.
Contributing #
Issues and PRs are welcome at github.com/cuatro-quinas/ajolote.
License #
MIT — see LICENSE.