This is the 21st day of my participation in the More text Challenge. For more details, see more text Challenge
While previous articles have covered Fluro’s route management and transition animations, this article shows you how to implement route interception and thus permission management. “I drove the road and planted the tree. If have no authority, 403 come!”
Related articles
To learn about the routing section of the Flutter, see the following section:
- Implementation of App page routing and route interception
- Introduction and Practice (XV) : Routing parameter processing
- Introduction to Flutter and Practice (XVI) : An introduction to Fluro route management
- Flutter Introduction and Combat (XVII) : Improve the page switching experience with Fluro’s transition animations
- Introduction to Flutter and Combat (XVIII) : Personalized page switching with custom transitions
Fluro route interception idea
Fluro itself does not provide the onGenerateRoute method that Flutter does to respond with route interception on each jump. Route interception can be implemented in two ways. One is to jump to the unauthorized page of 403 for an unauthorized route address when defining a route. The other is to inherit from FluroRouter and override some of its methods. By reading the source code, you can override the navigateTo method in subclasses for route interception.
Intercept when defining routes
This method is relatively simple. First, you need to define a routing table using Map and Map the routing processor corresponding to the routing path so that the routing path can be compared with the authorized routing table when defining the route. If the routing path is in the authorized routing table, the route is defined normally. Otherwise, use 403 unauthorized pages instead. The code looks like this:
// Complete routing table
static final routeTable = {
loginPath: Handler(
handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return LoginPage();
}),
dynamicDetailPath: Handler(
handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return DynamicDetailPage(params['id'] [0]);
}),
splashPath: Handler(
handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return Splash();
}),
transitionPath: Handler(
handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return TransitionPage();
}),
homePath: Handler(
handlerFunc: (BuildContext context, Map<String.dynamic> params) {
returnAppHomePage(); })};// Unauthorized page handler
static final permissionDeniedHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return PermissionDenied();
});
// Define the route
// When adding a route, compare the route path with the whitelist
// If the routing handler is not in the whitelist, an unauthorized routing handler is used
static void defineRoutes({List<String> whiteList}) {
routeTable.forEach((path, handler) {
if (whiteList == null || whiteList.contains(path)) {
router.define(path, handler: handler);
} else{ router.define(path, handler: permissionDeniedHandler, transitionType: TransitionType.material); }}); router.notFoundHandler = Handler( handlerFunc: (BuildContext context,Map<String.dynamic> params) {
return NotFound();
});
}
Copy the code
This method is simple to implement, but to ensure effective route interception, you must obtain the route whitelist through the login information before initializing the route. To improve user experience, you can specify in advance which pages (such as the splash screen, home page, and login page) do not involve permission control, and add these pages directly.
Jump intercept
The FluroRouter subclass is defined to override the navigatoTo method to intercept the route. What is a bit special here is that, since the path of the route jump may carry parameters, it cannot be directly compared to the whitelist as defined by route interception. However, you can define a route path matching method to determine whether the current route matches the whitelist and determine whether permission interception is required.
Fluro’s ability to route by path certainly provides a matching method for routing paths. If you look at the source code, you can see that there is a match method for matching routing paths. Return AppRouteMatch if a match is successful, or null if no match is found.
/// Finds a defined [AppRoute] for the path value.
/// If no [AppRoute] definition was found
/// then function will return null.
AppRouteMatch? match(String path) {
return _routeTree.matchRoute(path);
}
Copy the code
The AppRouteMatch class has an AppRoute class route attribute and a string route attribute under the route attribute, which is the matched route path.
class AppRoute {
String route;
dynamic handler;
TransitionType? transitionType;
Duration? transitionDuration;
RouteTransitionsBuilder? transitionBuilder;
AppRoute(this.route, this.handler,
{this.transitionType, this.transitionDuration, this.transitionBuilder});
}
Copy the code
Therefore, you can use this method to check whether the route matches the whitelist route. If the route does not match the whitelist route, you are directed to the 403 page. We define a subclass of FluroRouter, PermissionRouter, with two properties, the whitelist _whiteList and the 403 page routing address _permissionDeniedPath. In the overridden navigateTo method, the routing path matching mode is used to determine whether to intercept routes.
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
class PermissionRouter extends FluroRouter {
List<String> _whiteList;
set whiteList(value) => _whiteList = value;
String _permissionDeniedPath;
set permissionDeniedPath(value) => _permissionDeniedPath = value;
@override
Future navigateTo(
BuildContext context,
String path, {
bool replace = false.bool clearStack = false.bool maintainState = true.bool rootNavigator = false,
TransitionType transition,
Duration transitionDuration,
transitionBuilder,
RouteSettings routeSettings,
}) {
String pathToNavigate = path;
AppRouteMatch routeMatched = this.match(path);
StringroutePathMatched = routeMatched? .route? .route;if(routePathMatched ! =null) {
// If the whitelist is set and the current route is not in the whitelist, change the route path to the page where authorization is denied
if(_whiteList ! =null&&! _whiteList.contains(routePathMatched)) { pathToNavigate = _permissionDeniedPath; }}return super.navigateTo(context, pathToNavigate, replace: replace, clearStack: clearStack, maintainState: maintainState, rootNavigator: rootNavigator, transition: transition, transitionDuration: transitionDuration, transitionBuilder: transitionBuilder, routeSettings: routeSettings); }}Copy the code
In this way, routing handlers for all routes must be defined first, and then intercepted on jump. Therefore, assuming that the home page does not involve authorization, the authorization whitelist can be obtained after the App is started, rather than during the startup, which can reduce the tasks during startup, speed up startup and improve user experience.
conclusion
This article describes two ways to implement routing permission interception using Fluro routing management. Each approach has its own benefits, and you can decide which one to use depending on the actual situation.