Authentication
Introduction
Nylo Website v7 provides a comprehensive authentication system through the Auth class. It handles secure storage of user credentials, session management, and supports multiple named sessions for different auth contexts.
Auth data is stored securely and synced to Backpack (an in-memory key-value store) for fast, synchronous access throughout your app.
import 'package:nylo_framework/nylo_framework.dart';
// Authenticate a user
await Auth.authenticate(data: {"token": "abc123", "userId": 1});
// Check if authenticated
bool loggedIn = await Auth.isAuthenticated(); // true
// Get auth data
dynamic token = Auth.data(field: 'token'); // "abc123"
// Logout
await Auth.logout();
Authenticating Users
Use Auth.authenticate() to store user session data:
// With a Map
await Auth.authenticate(data: {
"token": "ey2sdm...",
"userId": 123,
"email": "user@example.com",
});
// With a Model class
User user = User(id: 123, email: "user@example.com", token: "ey2sdm...");
await Auth.authenticate(data: user);
// Without data (stores a timestamp)
await Auth.authenticate();
Real-World Example
class _LoginPageState extends NyPage<LoginPage> {
Future<void> handleLogin(String email, String password) async {
// 1. Call your API to authenticate
User? user = await api<AuthApiService>((request) => request.login(
email: email,
password: password,
));
if (user == null) {
showToastDanger(description: "Invalid credentials");
return;
}
// 2. Store the authenticated user
await Auth.authenticate(data: user);
// 3. Navigate to home
routeTo(HomePage.path, removeUntil: (_) => false);
}
}
Retrieving Auth Data
Get stored auth data using Auth.data():
// Get all auth data
dynamic userData = Auth.data();
print(userData); // {"token": "ey2sdm...", "userId": 123}
// Get a specific field
String? token = Auth.data(field: 'token');
int? userId = Auth.data(field: 'userId');
The Auth.data() method reads from Backpack (Nylo Website's in-memory key-value store) for fast synchronous access. Data is automatically synced to Backpack when you authenticate.
Updating Auth Data
Nylo Website v7 introduces Auth.set() to update auth data:
// Update a specific field
await Auth.set((data) {
data['token'] = 'new_token_value';
return data;
});
// Add new fields
await Auth.set((data) {
data['refreshToken'] = 'refresh_abc123';
data['lastLogin'] = DateTime.now().toIso8601String();
return data;
});
// Replace entire data
await Auth.set((data) => {
'token': newToken,
'userId': userId,
});
Logging Out
Remove the authenticated user with Auth.logout():
Future<void> handleLogout() async {
await Auth.logout();
// Navigate to login page
routeTo(LoginPage.path, removeUntil: (_) => false);
}
Logout from All Sessions
When using multiple sessions, clear them all:
// Logout from default and all named sessions
await Auth.logoutAll(sessions: ['device', 'admin']);
Checking Authentication
Check if a user is currently authenticated:
bool isLoggedIn = await Auth.isAuthenticated();
if (isLoggedIn) {
// User is authenticated
routeTo(HomePage.path);
} else {
// User needs to login
routeTo(LoginPage.path);
}
Multiple Sessions
Nylo Website v7 supports multiple named auth sessions for different contexts. This is useful when you need to track different types of authentication separately (e.g., user login vs device registration vs admin access).
// Default user session
await Auth.authenticate(data: user);
// Device authentication session
await Auth.authenticate(
data: {"deviceToken": "abc123"},
session: 'device',
);
// Admin session
await Auth.authenticate(
data: adminUser,
session: 'admin',
);
Reading from Named Sessions
// Default session
dynamic userData = Auth.data();
String? userToken = Auth.data(field: 'token');
// Device session
dynamic deviceData = Auth.data(session: 'device');
String? deviceToken = Auth.data(field: 'deviceToken', session: 'device');
// Admin session
dynamic adminData = Auth.data(session: 'admin');
Session-Specific Logout
// Logout from default session only
await Auth.logout();
// Logout from device session only
await Auth.logout(session: 'device');
// Logout from all sessions
await Auth.logoutAll(sessions: ['device', 'admin']);
Check Authentication per Session
bool userLoggedIn = await Auth.isAuthenticated();
bool deviceRegistered = await Auth.isAuthenticated(session: 'device');
bool isAdmin = await Auth.isAuthenticated(session: 'admin');
Device ID
Nylo Website v7 provides a unique device identifier that persists across app sessions:
String deviceId = await Auth.deviceId();
// Example: "550e8400-e29b-41d4-a716-446655440000-1704067200000"
The device ID is:
- Generated once and stored permanently
- Unique to each device/installation
- Useful for device registration, analytics, or push notifications
// Example: Register device with backend
Future<void> registerDevice() async {
String deviceId = await Auth.deviceId();
String? pushToken = await FirebaseMessaging.instance.getToken();
await api<DeviceApiService>((request) => request.register(
deviceId: deviceId,
pushToken: pushToken,
));
// Store device auth
await Auth.authenticate(
data: {"deviceId": deviceId, "pushToken": pushToken},
session: 'device',
);
}
Syncing to Backpack
Auth data is automatically synced to Backpack when you authenticate. To manually sync (e.g., on app boot):
// Sync default session
await Auth.syncToBackpack();
// Sync specific session
await Auth.syncToBackpack(session: 'device');
// Sync all sessions
await Auth.syncAllToBackpack(sessions: ['device', 'admin']);
This is useful in your app's boot sequence to ensure auth data is available in Backpack for fast synchronous access.
Initial Route
The initial route is the first page users see when they open your app. Set it using .initialRoute() in your router:
// routes/router.dart
appRouter() => nyRoutes((router) {
router.add(LoginPage.path).initialRoute();
router.add(HomePage.path);
});
You can also set a conditional initial route using the when parameter:
appRouter() => nyRoutes((router) {
router.add(OnboardingPage.path).initialRoute(
when: () => !hasCompletedOnboarding()
);
router.add(HomePage.path).initialRoute(
when: () => hasCompletedOnboarding()
);
});
Navigate back to the initial route from anywhere using routeToInitial():
void _goHome() {
routeToInitial();
}
Authenticated Route
The authenticated route overrides the initial route when a user is logged in. Set it using .authenticatedRoute():
appRouter() => nyRoutes((router) {
router.add(LoginPage.path).initialRoute();
router.add(HomePage.path).authenticatedRoute();
router.add(ProfilePage.path);
router.add(SettingsPage.path);
});
When the app boots:
Auth.isAuthenticated()returnstrue→ user sees the authenticated route (HomePage)Auth.isAuthenticated()returnsfalse→ user sees the initial route (LoginPage)
You can also set a conditional authenticated route:
router.add(HomePage.path).authenticatedRoute(
when: () => hasCompletedSetup()
);
Navigate to the authenticated route programmatically using routeToAuthenticatedRoute():
// After login
await Auth.authenticate(data: user);
routeToAuthenticatedRoute();
See also: Router for full routing documentation including guards and deep linking.
Preview Route
During development, you may want to quickly preview a specific page without changing your initial or authenticated route. Use .previewRoute():
appRouter() => nyRoutes((router) {
router.add(LoginPage.path).initialRoute();
router.add(HomePage.path).authenticatedRoute();
router.add(SettingsPage.path).previewRoute(); // Opens first during development
});
previewRoute() overrides both initialRoute() and authenticatedRoute(), making the specified route the first page shown regardless of auth state.
Warning: Remove
.previewRoute()before releasing your app.
Unknown Route
Define a fallback page for when a user navigates to a route that doesn't exist. Set it using .unknownRoute():
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(NotFoundPage.path).unknownRoute();
});
Putting It All Together
Here's a complete router setup with all route types:
appRouter() => nyRoutes((router) {
// First page for unauthenticated users
router.add(LoginPage.path).initialRoute();
// First page for authenticated users
router.add(HomePage.path).authenticatedRoute();
// 404 page
router.add(NotFoundPage.path).unknownRoute();
// Regular routes
router.add(ProfilePage.path);
router.add(SettingsPage.path);
});
| Route Method | Purpose |
|---|---|
.initialRoute() |
First page shown to unauthenticated users |
.authenticatedRoute() |
First page shown to authenticated users |
.previewRoute() |
Overrides both during development |
.unknownRoute() |
Shown when a route is not found |
Helper Functions
Nylo Website v7 provides helper functions that mirror the Auth class methods:
| Helper Function | Equivalent |
|---|---|
authAuthenticate(data: user) |
Auth.authenticate(data: user) |
authData() |
Auth.data() |
authData(field: 'token') |
Auth.data(field: 'token') |
authSet((data) => {...}) |
Auth.set((data) => {...}) |
authIsAuthenticated() |
Auth.isAuthenticated() |
authLogout() |
Auth.logout() |
authLogoutAll(sessions: [...]) |
Auth.logoutAll(sessions: [...]) |
authSyncToBackpack() |
Auth.syncToBackpack() |
authKey() |
Storage key for the default session |
authDeviceId() |
Auth.deviceId() |
All helpers accept the same parameters as their Auth class counterparts, including the optional session parameter:
// Authenticate with a named session
await authAuthenticate(data: device, session: 'device');
// Read from a named session
dynamic deviceData = authData(session: 'device');
// Check a named session
bool deviceAuth = await authIsAuthenticated(session: 'device');