Route Guards
परिचय
रूट गार्ड Nylo Website में नेविगेशन के लिए मिडलवेयर प्रदान करते हैं। ये रूट ट्रांज़िशन को इंटरसेप्ट करते हैं और आपको यह नियंत्रित करने की अनुमति देते हैं कि कोई उपयोगकर्ता किसी पेज तक पहुँच सकता है या नहीं, उसे कहीं और रीडायरेक्ट करना है, या रूट को भेजे गए डेटा को संशोधित करना है।
सामान्य उपयोग के मामले शामिल हैं:
- प्रमाणीकरण जाँच -- अप्रमाणित उपयोगकर्ताओं को लॉगिन पेज पर रीडायरेक्ट करना
- भूमिका-आधारित एक्सेस -- पेजों को एडमिन उपयोगकर्ताओं तक सीमित करना
- डेटा सत्यापन -- नेविगेशन से पहले सुनिश्चित करना कि आवश्यक डेटा मौजूद है
- डेटा संवर्धन -- रूट में अतिरिक्त डेटा जोड़ना
गार्ड नेविगेशन होने से पहले क्रम में निष्पादित होते हैं। यदि कोई गार्ड handled लौटाता है, तो नेविगेशन रुक जाता है (या तो रीडायरेक्ट या एबॉर्ट करके)।
रूट गार्ड बनाना
Metro CLI का उपयोग करके रूट गार्ड बनाएँ:
metro make:route_guard auth
यह एक गार्ड फ़ाइल जनरेट करता है:
import 'package:nylo_framework/nylo_framework.dart';
class AuthRouteGuard extends NyRouteGuard {
AuthRouteGuard();
@override
Future<GuardResult> onBefore(RouteContext context) async {
// Add your guard logic here
return next();
}
}
गार्ड जीवनचक्र
प्रत्येक रूट गार्ड में तीन जीवनचक्र मेथड होते हैं:
onBefore
नेविगेशन होने से पहले कॉल होता है। यहाँ आप शर्तें जाँचते हैं और तय करते हैं कि नेविगेशन की अनुमति देनी है, रीडायरेक्ट करना है, या एबॉर्ट करना है।
@override
Future<GuardResult> onBefore(RouteContext context) async {
bool isLoggedIn = await Auth.isAuthenticated();
if (!isLoggedIn) {
return redirect(HomePage.path);
}
return next();
}
रिटर्न मान:
next()-- अगले गार्ड पर जाएँ या रूट पर नेविगेट करेंredirect(path)-- एक अलग रूट पर रीडायरेक्ट करेंabort()-- नेविगेशन पूरी तरह रद्द करें
onAfter
सफल नेविगेशन के बाद कॉल होता है। इसे एनालिटिक्स, लॉगिंग, या नेविगेशन के बाद के साइड इफेक्ट्स के लिए उपयोग करें।
@override
Future<void> onAfter(RouteContext context) async {
// Log page view
Analytics.trackPageView(context.routeName);
}
onLeave
जब उपयोगकर्ता किसी रूट से बाहर जा रहा हो तब कॉल होता है। उपयोगकर्ता को बाहर जाने से रोकने के लिए false लौटाएँ।
@override
Future<bool> onLeave(RouteContext context) async {
if (hasUnsavedChanges) {
// Show confirmation dialog
return await showConfirmDialog();
}
return true; // Allow leaving
}
RouteContext
RouteContext ऑब्जेक्ट सभी गार्ड जीवनचक्र मेथड को पास किया जाता है और इसमें नेविगेशन के बारे में जानकारी होती है:
| प्रॉपर्टी | टाइप | विवरण |
|---|---|---|
context |
BuildContext? |
वर्तमान बिल्ड कॉन्टेक्स्ट |
data |
dynamic |
रूट को पास किया गया डेटा |
queryParameters |
Map<String, String> |
URL क्वेरी पैरामीटर |
routeName |
String |
लक्ष्य रूट का नाम/पथ |
originalRouteName |
String? |
ट्रांसफ़ॉर्मेशन से पहले का मूल रूट नाम |
@override
Future<GuardResult> onBefore(RouteContext context) async {
// Access route information
String route = context.routeName;
dynamic routeData = context.data;
Map<String, String> params = context.queryParameters;
return next();
}
रूट कॉन्टेक्स्ट को ट्रांसफ़ॉर्म करना
अलग डेटा के साथ एक कॉपी बनाएँ:
// Change the data type
RouteContext<User> userContext = context.withData<User>(currentUser);
// Copy with modified fields
RouteContext updated = context.copyWith(
data: enrichedData,
queryParameters: {"tab": "settings"},
);
गार्ड एक्शन
next
चेन में अगले गार्ड पर जाएँ, या यदि यह अंतिम गार्ड है तो रूट पर नेविगेट करें:
return next();
redirect
उपयोगकर्ता को एक अलग रूट पर रीडायरेक्ट करें:
return redirect(LoginPage.path);
अतिरिक्त विकल्पों के साथ:
return redirect(
LoginPage.path,
data: {"returnTo": context.routeName},
navigationType: NavigationType.pushReplace,
queryParameters: {"source": "guard"},
);
| पैरामीटर | टाइप | डिफ़ॉल्ट | विवरण |
|---|---|---|---|
path |
Object |
आवश्यक | रूट पथ स्ट्रिंग या RouteView |
data |
dynamic |
null | रीडायरेक्ट रूट को पास करने के लिए डेटा |
queryParameters |
Map<String, dynamic>? |
null | क्वेरी पैरामीटर |
navigationType |
NavigationType |
pushReplace |
नेविगेशन विधि |
result |
dynamic |
null | लौटाया जाने वाला रिज़ल्ट |
removeUntilPredicate |
Function? |
null | रूट हटाने का प्रेडिकेट |
transitionType |
TransitionType? |
null | पेज ट्रांज़िशन टाइप |
onPop |
Function(dynamic)? |
null | पॉप पर कॉलबैक |
abort
रीडायरेक्ट किए बिना नेविगेशन रद्द करें। उपयोगकर्ता अपने वर्तमान पेज पर बना रहता है:
return abort();
setData
बाद के गार्ड और लक्ष्य रूट को पास किए जाने वाले डेटा को संशोधित करें:
@override
Future<GuardResult> onBefore(RouteContext context) async {
User user = await fetchUser();
// Enrich the route data
setData({"user": user, "originalData": context.data});
return next();
}
रूट पर गार्ड लागू करना
अपनी राउटर फ़ाइल में अलग-अलग रूट में गार्ड जोड़ें:
appRouter() => nyRoutes((router) {
router.route(
HomePage.path,
(_) => HomePage(),
).initialRoute();
// Add a single guard
router.route(
ProfilePage.path,
(_) => ProfilePage(),
routeGuards: [AuthRouteGuard()],
);
// Add multiple guards (executed in order)
router.route(
AdminPage.path,
(_) => AdminPage(),
routeGuards: [AuthRouteGuard(), AdminRoleGuard()],
);
});
समूह गार्ड
रूट समूहों का उपयोग करके एक साथ कई रूट पर गार्ड लागू करें:
appRouter() => nyRoutes((router) {
router.route(HomePage.path, (_) => HomePage()).initialRoute();
// All routes in this group require authentication
router.group(() {
return {
'prefix': '/dashboard',
'route_guards': [AuthRouteGuard()],
};
}, (router) {
router.route(DashboardPage.path, (_) => DashboardPage());
router.route(SettingsPage.path, (_) => SettingsPage());
router.route(ProfilePage.path, (_) => ProfilePage());
});
});
गार्ड कम्पोज़िशन
Nylo Website पुन: उपयोग योग्य पैटर्न के लिए गार्ड को एक साथ कम्पोज़ करने के उपकरण प्रदान करता है।
GuardStack
कई गार्ड को एक पुन: उपयोग योग्य गार्ड में जोड़ें:
final protectedRoute = GuardStack([
AuthRouteGuard(),
VerifyEmailGuard(),
TwoFactorGuard(),
]);
// Use the stack on a route
router.route(
SecurePage.path,
(_) => SecurePage(),
routeGuards: [protectedRoute],
);
GuardStack गार्ड को क्रम में निष्पादित करता है। यदि कोई गार्ड handled लौटाता है, तो शेष गार्ड छोड़ दिए जाते हैं।
ConditionalGuard
गार्ड को केवल तभी लागू करें जब कोई शर्त सत्य हो:
router.route(
BetaPage.path,
(_) => BetaPage(),
routeGuards: [
ConditionalGuard(
condition: (context) => context.queryParameters.containsKey("beta"),
guard: BetaAccessGuard(),
),
],
);
यदि शर्त false लौटाती है, तो गार्ड को छोड़ दिया जाता है और नेविगेशन जारी रहता है।
ParameterizedGuard
कॉन्फ़िगरेशन पैरामीटर स्वीकार करने वाले गार्ड बनाएँ:
class RoleGuard extends ParameterizedGuard<List<String>> {
RoleGuard(super.params); // params = allowed roles
@override
Future<GuardResult> onBefore(RouteContext context) async {
User? user = await Auth.user<User>();
if (user == null || !params.contains(user.role)) {
return redirect(UnauthorizedPage.path);
}
return next();
}
}
// Usage
router.route(
AdminPage.path,
(_) => AdminPage(),
routeGuards: [RoleGuard(["admin", "super_admin"])],
);
उदाहरण
प्रमाणीकरण गार्ड
class AuthRouteGuard extends NyRouteGuard {
AuthRouteGuard();
@override
Future<GuardResult> onBefore(RouteContext context) async {
bool isAuthenticated = await Auth.isAuthenticated();
if (!isAuthenticated) {
return redirect(HomePage.path);
}
return next();
}
}
पैरामीटर के साथ सब्सक्रिप्शन गार्ड
class SubscriptionGuard extends ParameterizedGuard<List<String>> {
SubscriptionGuard(super.params);
@override
Future<GuardResult> onBefore(RouteContext context) async {
User? user = await Auth.user<User>();
bool hasAccess = params.any((plan) => user?.subscription == plan);
if (!hasAccess) {
return redirect(UpgradePage.path, data: {"plans": params});
}
setData({"user": user});
return next();
}
}
// Require premium or pro subscription
router.route(
PremiumPage.path,
(_) => PremiumPage(),
routeGuards: [
AuthRouteGuard(),
SubscriptionGuard(["premium", "pro"]),
],
);
लॉगिंग गार्ड
class LoggingGuard extends NyRouteGuard {
LoggingGuard();
@override
Future<GuardResult> onBefore(RouteContext context) async {
print("Navigating to: ${context.routeName}");
return next();
}
@override
Future<void> onAfter(RouteContext context) async {
print("Arrived at: ${context.routeName}");
}
}