How does Flutter complete route interception and realize authority management

  • 2021-12-13 09:34:20
  • OfStack

Catalog related articles fluro route interception idea Intercept when defining routes Intercept when jumping

The previous articles introduced the route management and transition animation of fluro. This article introduces how to complete route interception and then realize permission management. "I opened this road and planted this tree. If there is no authority, 403 will come!"

Related articles

To learn about the routing chapters of flutter, please refer to the following chapters:

//www.ofstack.com/article/215167.htm

//www.ofstack.com/article/214856.htm

//www.ofstack.com/article/215564.htm

//www.ofstack.com/article/215549.htm

//www.ofstack.com/article/215569.htm

Idea of fluro Route Interception

The fluro itself does not provide a method similar to the onGenerateRoute that comes with the Flutter for routing interception response at each jump. We can realize route interception in two ways: 1. When defining routes, we jump to 403 unauthorized page for unauthorized routing addresses; 2 inherits the FluroRouter class and overrides some of its methods. By reading the source code, we can find that the navigateTo method can be overwritten in subclasses for route interception.

Intercept when defining routes

This method is relatively simple. First, it is necessary to use Map to define a routing table, and make a mapping to the routing processor corresponding to the routing path, so as to compare the routing path with the authorized routing table when defining the route. If it is in the authorized routing table, the route will be defined normally; Otherwise, use 403 unauthorized page replacement. 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) {
    return AppHomePage();
  }),
};

// Unauthorized page handler 
static final permissionDeniedHandler =
    Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) {
  return PermissionDenied();
});

// Define a route 
// When adding a route, compare the route path with the white list 
// If it is not in the white list, the unauthorized routing processor 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();
  });
}

This method is simple to implement, but in order to ensure that the route interception is effective, the route whitelist must be obtained through the login information before initializing the route. In order to improve the user experience, you can specify which pages do not involve permission control in advance (such as flash screen page, home page and login page), and add these pages directly.

Intercept when jumping

Jump interception needs to define another subclass of FluroRouter, and realize route interception by overriding navigatoTo method. What is special here is that because the path when the route jumps may carry parameters, it cannot be directly compared with the white list like defining the route interception. However, one route path matching method can be defined to judge whether the current route matches the whitelist and decide whether to do permission interception.

Since fluro can definitely provide the corresponding routing path matching method according to the path routing, we can find that there is one match method for matching the routing path. If the match is successful, the matching routing object AppRouteMatch is returned, and if it is not matched, null is returned.


/// 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);
}

The AppRouteMatch class has an route attribute of the AppRoute class, and under the route attribute, there is also an route attribute of string type, which is the matching routing path.


class AppRoute {
  String route;
  dynamic handler;
  TransitionType? transitionType;
  Duration? transitionDuration;
  RouteTransitionsBuilder? transitionBuilder;
  AppRoute(this.route, this.handler,
      {this.transitionType, this.transitionDuration, this.transitionBuilder});
}

Therefore, we can check whether it matches the whitelist route in this way, and if it does not match, we will go to page 403. We define a subclass of FluroRouter, PermissionRouter, which has two attributes, namely the whitelist list _ whiteList and the 403 page routing address _ permissionDeniedPath. In the overlay navigateTo method, routing path matching is used to decide whether to carry out route interception or not.


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);
    String routePathMatched = routeMatched?.route?.route;
    if (routePathMatched != null) {
      // Whitelist is set and the current route is not in the whitelist, change the route path to the Authorization Denied page 
      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);
  }
}

In this way, it is necessary to define the routing processor corresponding to all routes first, and then intercept them when jumping. Therefore, assuming that the homepage does not involve authorization, the authorization whitelist can be obtained after App starts, instead of being obtained at startup, which can reduce the task at startup, speed up startup and improve user experience.

The above is Flutter how to complete the route interception, the implementation of rights management details, more information about Flutter route interception please pay attention to this site other related articles!


Related articles: