如何为Flutter路由添加全局鉴权中间件实现长时间无操作跳转登录页
实现方案
1. 全局无操作检测逻辑
通过WidgetsApp的builder属性全局包裹交互监听器,捕获所有用户触摸、点击、键盘输入等操作,每次操作重置超时计时器,计时器触发时自动跳转登录页,适配Web、移动端双端场景。
代码示例:
// 全局NavigatorKey,无需依赖页面上下文即可调用导航 final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); // 超时时间可自定义,示例为15分钟 const _inactiveTimeout = Duration(minutes: 15); Timer? _inactiveTimer; // 重置超时计时器 void _resetInactiveTimer() { _inactiveTimer?.cancel(); _inactiveTimer = Timer(_inactiveTimeout, () { // 超时后跳登录页并清空路由栈,禁止返回之前页面 navigatorKey.currentState?.pushNamedAndRemoveUntil('/login', (route) => false); }); } // MaterialApp 配置 MaterialApp( navigatorKey: navigatorKey, builder: (context, child) { return Listener( // 监听所有触摸、点击操作 onPointerDown: (_) => _resetInactiveTimer(), onPointerMove: (_) => _resetInactiveTimer(), onPointerUp: (_) => _resetInactiveTimer(), // 适配Web端键盘操作监听 child: Shortcuts( shortcuts: { const SingleActivator(LogicalKeyboardKey.any): CallbackAction(onInvoke: (_) => _resetInactiveTimer()), }, child: child!, ), ); }, onGenerateRoute: _handleGenerateRoute, initialRoute: '/login', )
2. 统一路由鉴权中间件实现
无需在每个Navigator.push调用前单独加判断,通过onGenerateRoute钩子统一处理所有路由跳转的鉴权逻辑:
Route? _handleGenerateRoute(RouteSettings settings) { // 无需鉴权的路由白名单,比如登录、注册页 final whiteListRoutes = ['/login', '/register']; if (whiteListRoutes.contains(settings.name)) { // 白名单路由直接放行 return MaterialPageRoute(builder: (_) => getPageByRouteName(settings.name!)); } // 非白名单路由先校验用户认证状态 if (localAuth.isUserAuthenticated()) { // 已认证直接放行 return MaterialPageRoute(builder: (_) => getPageByRouteName(settings.name!)); } // 未认证跳转登录页 return MaterialPageRoute(builder: (_) => const LoginPage()); }
补充说明
- 如果使用
go_router等第三方路由库,可直接使用库自带的全局redirect配置实现统一鉴权,无需自行实现onGenerateRoute - 登录成功后需要手动调用一次
_resetInactiveTimer()初始化计时器,避免刚登录就触发超时跳转 - 若需要更精细化的路由权限控制,可在
_handleGenerateRoute中拓展不同角色的路由访问规则
内容的提问来源于stack exchange,提问作者Ali Azimoshan
相关产品推荐
相关产品推荐

