Setting Up the Auth SDK
What you'll learn
- Generating the Auth SDK feature with API/Impl split
- Understanding the generated login/register pages
- Customizing the event-driven auth listener pattern
- Connecting auth state to your app's navigation
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
- Network SDK already generated (see Network SDK Setup)
Step 1: Generate the Auth SDK
bash
archipelago generate auth_sdkYou will be prompted for:
- appName —
MyApp(must match your monorepo app name) - isForMonorepo —
true(uses workspace path resolution)
Or use a config file:
json
{
"appName": "MyApp",
"isForMonorepo": true
}bash
archipelago generate auth_sdk --config auth_config.jsonStep 2: Understand the Generated Structure
The Auth SDK uses the API/Impl split pattern because other features commonly depend on auth state:
features/
├── auth_sdk_api/
│ └── lib/src/
│ └── auth_sdk.dart # FeatureSDK contract
└── auth_sdk_impl/
└── lib/src/
├── auth_sdk_impl.dart # Implementation
├── data/
│ ├── datasources/ # Token storage, API calls
│ ├── models/ # User model, token model
│ └── repositories/ # Auth repository impl
├── di/ # Scoped DI registration
├── domain/
│ ├── repositories/ # Auth repository contract
│ └── usecases/ # Login, register, logout
├── presentation/
│ └── ui/pages/ # Login & register pages
└── router/ # Auth route definitionsStep 3: Register the Auth Feature
In your shell app's bootstrap.dart, register the auth SDK:
dart
import 'package:auth_sdk_impl/auth_sdk_impl.dart';
FeatureRegistry.register(AuthSdkImpl());Other features that need auth state depend on auth_sdk_api only:
yaml
# In another feature's pubspec.yaml
dependencies:
auth_sdk_api:
path: ../../features/auth_sdk_apiStep 4: Customize the Auth Flow
The generated auth uses an event-driven listener pattern. The AuthSdkImpl exposes a stream of auth state changes:
dart
// Listen to auth state in your router or shell
authRepository.authStateStream.listen((state) {
switch (state) {
case Authenticated():
router.go('/home');
case Unauthenticated():
router.go('/login');
}
});Step 5: Connect to Your API
Edit the remote datasource to point to your backend:
dart
// auth_sdk_impl/lib/src/data/datasources/remote/auth_remote_datasource.dart
class AuthRemoteDatasource {
final NetworkClient _client;
Future<TokenModel> login(String email, String password) {
return _client.post('/auth/login', body: {
'email': email,
'password': password,
});
}
Future<TokenModel> register(String name, String email, String password) {
return _client.post('/auth/register', body: {
'name': name,
'email': email,
'password': password,
});
}
}Step 6: Token Storage
The generated datasource includes secure token storage using flutter_secure_storage. Tokens are persisted across app restarts and automatically attached to network requests via the Network SDK's interceptor.
dart
// auth_sdk_impl/lib/src/data/datasources/local/auth_local_datasource.dart
class AuthLocalDatasource {
final FlutterSecureStorage _storage;
Future<void> saveToken(TokenModel token) async {
await _storage.write(key: 'access_token', value: token.accessToken);
await _storage.write(key: 'refresh_token', value: token.refreshToken);
}
Future<String?> getAccessToken() =>
_storage.read(key: 'access_token');
}Common Customizations
| Customization | Where to Change |
|---|---|
| Add social login | AuthRemoteDatasource — add OAuth methods |
| Change token format | TokenModel — update JSON parsing |
| Add biometric auth | AuthLocalDatasource — integrate local_auth |
| Custom login UI | presentation/ui/pages/ — modify page widgets |
| Add OTP verification | domain/usecases/ — add VerifyOtpUseCase |
Next Steps
- Set up the UI Kit to theme your login pages
- Configure monitoring to track auth failures