Authentication
Secure authentication flows with Login, Register, and Social Sign-in.
Overview
The authentication system in this Flutter boilerplate is built for security, scalability, and developer productivity. It leverages Riverpod for state management and Flutter Secure Storage for token persistence.
Key features include:
- State-driven authentication flow: The UI reacts automatically to changes in authentication status.
- Secure persistence: Sensitive data like JWT tokens is stored in the device's secure enclave.
- Hybrid Methods: Support for traditional Email/Password and social login via Google.
- Deep Linked Recovery: Automated "Forgot Password" flow utilizing custom deep link schemes to redirect users back to the app.
Core State Management
Authentication state is managed by the AuthNotifier (a Riverpod AsyncNotifier).
AuthStatus
The app follows three distinct authentication states:
authenticated: User is logged in and token is valid.unauthenticated: User is logged out or session has expired.loading: An authentication process (login, register, logout) is in progress.
Usage in Widgets
You can react to authentication changes anywhere in your widget tree:
final authStatus = ref.watch(authProvider);
switch (authStatus) {
case AuthStatus.authenticated:
return const HomeScreen();
case AuthStatus.unauthenticated:
return const LoginScreen();
case AuthStatus.loading:
return const LoadingSpinner();
}Authentication Methods
Email & Password
The standard flow involves sending credentials to the backend, receiving a JWT/Bearer token, and persisting it locally.
Registration:
await ref.read(authProvider.notifier).register(
name: 'John Doe',
email: 'john@example.com',
password: 'securepassword',
);Login:
await ref.read(authProvider.notifier).login(
email: 'john@example.com',
password: 'securepassword',
);Google Sign-In
Native Google login is integrated using the google_sign_in package. The flow involves:
- Native OS authentication dialog.
- Exchange Google ID Token for a backend session token.
- Synchronize FCM (Firebase Cloud Messaging) tokens for push notifications.
await ref.read(authProvider.notifier).loginWithGoogle();Session Management
Automatic Verification
On app startup, the checkAuth() method is triggered in main.dart. It verifies if a stored token exists and validates it against the backend. If the token is invalid, the user is automatically redirected to the login screen.
Secure Storage
We use FlutterSecureStorage with EncryptedSharedPreferences on Android to ensure that tokens and user data are encrypted at rest.
Token Injection
The DioService automatically intercepts outgoing requests to inject the Authorization: Bearer <token> header, ensuring seamless authenticated API calls.
Password Recovery & Deep Linking
The "Forgot Password" flow is fully automated:
- User requests a reset link via the app.
- User receives an email with a deep link (e.g.,
appschema_name://reset-password?token=...). - Tapping the link opens the app directly to the
ResetPasswordPage. - The token is automatically extracted from the URI and used for the final password update.
Email Verification
The system supports mandatory email verification. Users can trigger a verification email from their profile or during the onboarding flow. The backend tracks the email_verified_at timestamp to gate access to specific features if necessary.
await ref.read(authProvider.notifier).sendVerificationEmail();Push Notification Integration
Authentication is tightly coupled with Firebase Cloud Messaging (FCM). Upon successful login or registration, the device's FCM token is synchronized with the backend, allowing users to receive targeted push notifications immediately.
Security & Token Architecture
Personal Access Tokens (PAT)
The application utilizes a Personal Access Token system (powered by Laravel Sanctum). Unlike session cookies, these tokens are:
- Revocable: Users or admins can revoke specific device tokens without affecting other sessions.
- Strictly Scoped: Each token is issued with specific abilities/permissions. The backend validates every request against these scopes to ensure the token hasn't been compromised for unauthorized actions.
- Hardware Bound: Tokens are coupled with the
device_nameduring issuance, providing an audit trail of which physical devices are accessing the account.
Security Best Practices
- Clear on Logout: Manual logout or token expiration triggers a complete wipe of secure storage (
token,user_data, andfcmToken). - Device identification: Every session is tracked with a device name (e.g., "Apple iPhone 15") for better security auditing in the backend.
- Scoped Permissions: The app logic respects the granular permissions associated with the token, preventing unauthorized feature access at both the UI and API levels.
- Optimistic Updates: Using Riverpod's state transitions, the UI feels fast and responsive even during network-intensive auth tasks.