Skip to content

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

Step 1: Generate the Auth SDK

bash
archipelago generate auth_sdk

You will be prompted for:

  • appNameMyApp (must match your monorepo app name)
  • isForMonorepotrue (uses workspace path resolution)

Or use a config file:

json
{
  "appName": "MyApp",
  "isForMonorepo": true
}
bash
archipelago generate auth_sdk --config auth_config.json

Step 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 definitions

Step 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_api

Step 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

CustomizationWhere to Change
Add social loginAuthRemoteDatasource — add OAuth methods
Change token formatTokenModel — update JSON parsing
Add biometric authAuthLocalDatasource — integrate local_auth
Custom login UIpresentation/ui/pages/ — modify page widgets
Add OTP verificationdomain/usecases/ — add VerifyOtpUseCase

Next Steps

Built by Banua Coder