Flutter 通過自定義路由攔截實(shí)現(xiàn)權(quán)限管理

之前幾篇介紹了 fluro 的路由管理和轉(zhuǎn)場動畫智末,本篇介紹如何完成路由攔截,進(jìn)而實(shí)現(xiàn)權(quán)限管理徒河∠倒荩“此路是我開,此樹是我栽顽照。若是沒權(quán)限由蘑,403到來!”

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類有一個AppRouteroute屬性,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)。

總結(jié)

本篇介紹了利用 fluro 路由管理實(shí)現(xiàn)路由權(quán)限攔截的兩種方式遍膜,兩種方式各有好處碗硬,使用過程中可以根據(jù)實(shí)際情況決定使用哪一種方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓢颅,一起剝皮案震驚了整個濱河市恩尾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挽懦,老刑警劉巖特笋,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異巾兆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虎囚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門角塑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淘讥,你說我怎么就攤上這事圃伶。” “怎么了蒲列?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵窒朋,是天一觀的道長。 經(jīng)常有香客問我蝗岖,道長侥猩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任抵赢,我火速辦了婚禮欺劳,結(jié)果婚禮上唧取,老公的妹妹穿的比我還像新娘。我一直安慰自己划提,他們只是感情好枫弟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹏往,像睡著了一般淡诗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伊履,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天韩容,我揣著相機(jī)與錄音,去河邊找鬼湾碎。 笑死宙攻,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的介褥。 我是一名探鬼主播座掘,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼柔滔!你這毒婦竟也來了溢陪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤睛廊,失蹤者是張志新(化名)和其女友劉穎形真,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體超全,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咆霜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘶朱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛾坯。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疏遏,靈堂內(nèi)的尸體忽然破棺而出脉课,到底是詐尸還是另有隱情,我是刑警寧澤财异,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布倘零,位于F島的核電站,受9級特大地震影響戳寸,放射性物質(zhì)發(fā)生泄漏呈驶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一疫鹊、第九天 我趴在偏房一處隱蔽的房頂上張望俐东。 院中可真熱鬧跌穗,春花似錦、人聲如沸虏辫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砌庄。三九已至羹唠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娄昆,已是汗流浹背佩微。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留萌焰,地道東北人哺眯。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像扒俯,于是被迫代替她去往敵國和親奶卓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容