Files
minhthu/lib/features/auth/QUICK_REFERENCE.md
2025-10-28 00:09:46 +07:00

5.4 KiB

Authentication Feature - Quick Reference

Import

import 'package:minhthu/features/auth/auth.dart';

Common Usage Patterns

1. Login

ref.read(authProvider.notifier).login(username, password);

2. Logout

ref.read(authProvider.notifier).logout();

3. Check if Authenticated

final isAuthenticated = ref.watch(isAuthenticatedProvider);

4. Get Current User

final user = ref.watch(currentUserProvider);
if (user != null) {
  print('Logged in as: ${user.username}');
}

5. Watch Auth State

final authState = ref.watch(authProvider);

if (authState.isLoading) {
  return LoadingIndicator();
}

if (authState.error != null) {
  return ErrorView(message: authState.error!);
}

if (authState.isAuthenticated) {
  return HomeView(user: authState.user!);
}

return LoginView();

6. Listen to Auth Changes

ref.listen(authProvider, (previous, next) {
  if (next.isAuthenticated) {
    context.go('/home');
  } else if (next.error != null) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(next.error!)),
    );
  }
});

Key Classes

AuthState

class AuthState {
  final UserEntity? user;
  final bool isAuthenticated;
  final bool isLoading;
  final String? error;
}

UserEntity

class UserEntity {
  final String userId;
  final String username;
  final String accessToken;
  final String? refreshToken;
}

LoginRequestModel

final request = LoginRequestModel(
  username: 'john.doe',
  password: 'secure123',
);

Providers

Provider Type Description
authProvider StateNotifier<AuthState> Main auth state
isAuthenticatedProvider bool Check auth status
currentUserProvider UserEntity? Get current user
isAuthLoadingProvider bool Check loading state
authErrorProvider String? Get error message

API Endpoints

Endpoint Method Description
/api/v1/auth/login POST Login
/api/v1/auth/logout POST Logout
/api/v1/auth/refresh POST Refresh token

Error Types

  • ValidationFailure - Invalid input
  • AuthenticationFailure - Login failed
  • NetworkFailure - Network error
  • ServerFailure - Server error

Protected Route Example

class MyPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final authState = ref.watch(authProvider);

    if (!authState.isAuthenticated) {
      return LoginPage();
    }

    return Scaffold(
      appBar: AppBar(
        title: Text('Protected Page'),
        actions: [
          IconButton(
            icon: Icon(Icons.logout),
            onPressed: () => ref.read(authProvider.notifier).logout(),
          ),
        ],
      ),
      body: Center(
        child: Text('Hello, ${authState.user!.username}!'),
      ),
    );
  }
}

Common Patterns

Check Auth on App Start

@override
void initState() {
  super.initState();
  Future.microtask(() {
    ref.read(authProvider.notifier).checkAuthStatus();
  });
}

Show Loading Overlay

if (ref.watch(isAuthLoadingProvider)) {
  return Stack(
    children: [
      yourContent,
      LoadingIndicator.overlay(),
    ],
  );
}

Conditional Navigation

ref.listen(authProvider, (previous, next) {
  if (!previous!.isAuthenticated && next.isAuthenticated) {
    context.go('/home');
  } else if (previous.isAuthenticated && !next.isAuthenticated) {
    context.go('/login');
  }
});

Testing Helpers

// Mock auth state
final mockAuthState = AuthState.authenticated(
  UserEntity(
    userId: '123',
    username: 'test',
    accessToken: 'token',
  ),
);

// Create test container
final container = ProviderContainer(
  overrides: [
    authProvider.overrideWith((ref) => MockAuthNotifier()),
  ],
);

Files Reference

Layer File Purpose
Data login_request_model.dart Request DTO
user_model.dart User DTO
auth_remote_datasource.dart API calls
auth_repository_impl.dart Repository impl
Domain user_entity.dart Domain entity
auth_repository.dart Repository interface
login_usecase.dart Business logic
Presentation login_page.dart Login UI
login_form.dart Form widget
auth_provider.dart State management
DI auth_dependency_injection.dart Providers setup

Troubleshooting Quick Fixes

Issue Solution
Provider not found Add ProviderScope to main.dart
Navigation fails Check router configuration
Tokens not saved Verify secure storage setup
API calls fail Check base URL in constants
State not updating Use ConsumerWidget

Performance Tips

  1. Use ref.read() for one-time operations
  2. Use ref.watch() for reactive updates
  3. Use ref.listen() for side effects
  4. Avoid rebuilding entire tree - scope providers
  5. Use select() for partial state watching

Security Checklist

  • Tokens in secure storage
  • Password fields obscured
  • No logging of sensitive data
  • Token auto-added to headers
  • Token cleared on logout
  • Input validation
  • HTTPS only (configure in production)
  • Token expiration handling
  • Rate limiting
  • Biometric auth (optional)