Flutter如何完成路由攔截,實(shí)現(xiàn)權(quán)限管理
之前幾篇介紹了 fluro 的路由管理和轉(zhuǎn)場動畫,本篇介紹如何完成路由攔截,進(jìn)而實(shí)現(xiàn)權(quán)限管理。“此路是我開,此樹是我栽。若是沒權(quán)限,403到來!”
相關(guān)文章
若想了解 flutter 的路由相關(guān)篇章,請查閱下面的篇章:
//www.dbjr.com.cn/article/215167.htm
//www.dbjr.com.cn/article/214856.htm
//www.dbjr.com.cn/article/215564.htm
//www.dbjr.com.cn/article/215549.htm
//www.dbjr.com.cn/article/215569.htm
fluro 路由攔截思路
fluro 本身并沒有提供類似 Flutter 自帶的 onGenerateRoute方法來在每次跳轉(zhuǎn)時進(jìn)行路由攔截響應(yīng)。我們可以通過兩種方式實(shí)現(xiàn)路由攔截,一是在定義路由的時候,對于未授權(quán)的路由地址跳轉(zhuǎn)到403未授權(quán)頁面;二是繼承 FluroRouter 類,重寫其中的部分方法。通過閱讀源碼可以發(fā)現(xiàn)可以在子類覆蓋 navigateTo 方法來進(jìn)行路由攔截。
定義路由時攔截
這種方式比較簡單,首先需要使用 Map定義一個路由表,將路由路徑對應(yīng)的路由處理器做一個映射,以便在定義路由的時候?qū)⒙酚陕窂脚c授權(quán)路由表進(jìn)行比較,若在授權(quán)路由表內(nèi),則正常定義路由;否則使用403未授權(quán)頁面替換。代碼如下所示:
//完整路由表 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(); }), }; //未授權(quán)頁面處理器 static final permissionDeniedHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return PermissionDenied(); }); //定義路由 //添加路由時,將路由路徑與白名單進(jìn)行比對 //若不在白名單內(nèi),則使用未授權(quán)路由處理器 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(); }); }
這種方式實(shí)現(xiàn)起來簡單,但是為了保證路由攔截有效,必須在初始化路由前就通過登錄人信息拿到路由白名單。為了改善用戶體驗(yàn),可以預(yù)先明確哪些頁面不涉及權(quán)限管控(如閃屏頁,首頁,登錄頁),將這些頁面直接添加。
跳轉(zhuǎn)時攔截
跳轉(zhuǎn)時攔截需要另外定義 FluroRouter 的子類,通過覆蓋navigatoTo方法來實(shí)現(xiàn)路由攔截。這里有點(diǎn)特殊的是,由于路由跳轉(zhuǎn)時的路徑可能攜帶參數(shù),不能像定義路由攔截那樣直接和白名單進(jìn)行比對。但是可以定義一個路由路徑匹配方法來判斷當(dāng)前路由和白名單的是否匹配決定是否要做權(quán)限攔截。
fluro 既然能夠按路徑路由肯定提供了對應(yīng)的路由路徑匹配方法,扒一下源碼,可以發(fā)現(xiàn)有一個match方法用于匹配路由路徑。如果匹配成功,則返回匹配的路由對象AppRouteMatch,如果沒有匹配到則返回 null。
/// 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); }
AppRouteMatch類有一個AppRoute類 route屬性,route屬性下還有一個 字符串類型的route屬性,即匹配到的路由路徑。
class AppRoute { String route; dynamic handler; TransitionType? transitionType; Duration? transitionDuration; RouteTransitionsBuilder? transitionBuilder; AppRoute(this.route, this.handler, {this.transitionType, this.transitionDuration, this.transitionBuilder}); }
因此可以通過該方式來檢測是否和白名單的路由匹配,如果不匹配就調(diào)到403頁面。我們定義了一個FluroRouter 的子類PermissionRouter,有兩個屬性,分別是 白名單列表_whiteList 和403頁面路由地址 _permissionDeniedPath。在覆蓋的 navigateTo方法中通過路由路徑匹配方式來決定是否進(jìn)行路由攔截。
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) { //設(shè)置了白名單且當(dāng)前路由不在白名單內(nèi),更改路由路徑到授權(quán)被拒絕頁面 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); } }
這種方式需要首先定義好全部路由對應(yīng)的路由處理器,然后在跳轉(zhuǎn)時再攔截。因此假設(shè)首頁是不涉及授權(quán)的,可以在 App 啟動后再獲取授權(quán)白名單,而不需要在啟動時獲取,可以降低啟動時的任務(wù),加快啟動速度和提高用戶體驗(yàn)。
以上就是Flutter如何完成路由攔截,實(shí)現(xiàn)權(quán)限管理的詳細(xì)內(nèi)容,更多關(guān)于Flutter 路由攔截的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android嵌套滾動和協(xié)調(diào)滾動的多種實(shí)現(xiàn)方法
嵌套的滾動主要方式就是這些,這些簡單的效果我們用協(xié)調(diào)滾動,如?CoordinatorLayout?也能實(shí)現(xiàn)同樣的效果,這篇文章主要介紹了Android嵌套滾動和協(xié)調(diào)滾動的多種實(shí)現(xiàn)方法,需要的朋友可以參考下2022-06-06Android如何監(jiān)測文件夾內(nèi)容變化詳解
最近在開發(fā)android應(yīng)用程序的時候遇到了一個監(jiān)測文件夾的功能,所以下面這篇文章主要給大家介紹了關(guān)于Android如何監(jiān)測文件夾內(nèi)容變化的相關(guān)資料,需要的朋友可以參考下2021-12-12安卓(Android)動態(tài)創(chuàng)建多個按鈕并添加監(jiān)聽事件
本文主要介紹Android動態(tài)創(chuàng)建多個按鈕并給每個按鍵添加監(jiān)聽事件,在做Android項(xiàng)目會經(jīng)常遇到的,希望對需要用到的同學(xué)有所幫助2016-07-07Android入門之使用RecyclerView完美實(shí)現(xiàn)瀑布流界面詳解
網(wǎng)上充滿著不完善的基于RecyclerView的瀑布流實(shí)現(xiàn),要么根本是錯的、要么就是只知其一不知其二。本文就來用RecyclerView完美實(shí)現(xiàn)瀑布流界面,希望大家有所幫助2023-02-02Android自定義TextView實(shí)現(xiàn)文字傾斜效果
有時候Android自帶的控件無法滿足我們的某些要求,這時就需要我們自定義控件來實(shí)現(xiàn)這些功能。比如在實(shí)際開發(fā)應(yīng)用中,我們有時需要將TextView的文字傾斜一定的角度,就需要自定義TextView。下面這篇文章就給大家介紹了利用Android TextView如何實(shí)現(xiàn)文字傾斜效果。2016-11-11Android自定義View實(shí)現(xiàn)五子棋游戲
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Android 中ListView setOnItemClickListener點(diǎn)擊無效原因分析
這篇文章主要介紹了Android 中ListView setOnItemClickListener點(diǎn)擊無效原因分析的相關(guān)資料,需要的朋友可以參考下2016-01-01Ubuntu Android源碼以及內(nèi)核下載與編譯
本文主要介紹Android源碼的下載和編譯,這里整理了相關(guān)資料及如何下載和編譯的詳細(xì)步驟,有需要的小伙伴可以參考下2016-09-09