【问题标题】:Making Private Route in Flutter在 Flutter 中创建私有路由
【发布时间】:2020-11-17 14:38:50
【问题描述】:

如何对我的私有路由进行包装,仅当用户被授权时才导航到屏幕,否则重定向到登录并在登录后返回原始屏幕。 如何以一种通用的方式实现这一点,以便我在其他 Private 未来屏幕上重复使用它?

【问题讨论】:

  • 您是否使用 Firebase 登录?
  • 不,从我自己的节点服务器简单登录。没有火力基地。
  • 您是否在入口点使用routes 映射?

标签: flutter dart flutter-redux


【解决方案1】:

使用StreamBuilder 小部件并为其提供访问令牌/uid 流,如果没有数据,则返回登录屏幕,当用户通过身份验证时,然后将访问令牌放入流中,该流将重建 StreamBuilder,当用户返回页面时已通过身份验证。

使用 bloc 模式或 bloc 库进行更好的状态管理。 希望这会对你有所帮助。

【讨论】:

  • 我没有使用来自我的节点服务器的流进行身份验证。还是会看看的。
  • 在 dart 中创建一个 Stream,并在用户通过身份验证时将数据放入其中。
  • 我猜,他已经有一些静态变量,表示用户是否登录。另外,流不会解决路由问题。对于初学者来说,bloc 也可能是一种矫枉过正
【解决方案2】:

如果您在MaterialApp 中使用routes 参数,则可以将其替换为以下实现

import 'dart:collection';

import 'package:flutter/widgets.dart';

class ConditionalRouter extends MapMixin<String, WidgetBuilder> {
  final Map<String, WidgetBuilder> public;
  final Map<String, WidgetBuilder> private;

  ConditionalRouter({this.public, this.private});

  @override
  WidgetBuilder operator [](Object key) {
    if (public.containsKey(key))
      return public[key];
    if (private.containsKey(key)) {
      if (MyAuth.isUserLoggedIn)
        return private[key];
      // Adding next page parameter to your Login page
      // will allow you to go back to page, that user were going to
      return (context) => LoginPage(nextPage: key);
    }
    return null;
  }

  @override
  void operator []=(key, value) {}

  @override
  void clear() {}

  @override
  Iterable<String> get keys {
    final set = Set<String>();
    set.addAll(public.keys);
    set.addAll(private.keys);
    return set;
  }

  @override
  WidgetBuilder remove(Object key) {
    return public[key] ?? private[key];
  }
}

然后像这样使用它:

MaterialApp(
  // ...
  routes: ConditionalRouter(
    public: {
      '/start_page': (context) => StartPage()
    },
    private: {
      '/user_profile': (context) => UserProfilePage()
    }
  )
)

【讨论】:

  • 感谢您提供有趣的解决方案。在解决方案中使用异步“Auth().isAuth()”函数方法而不是“MyAuth.isUserLoggedIn”的可能性是什么?我尝试了很多变体,但没有一个工作:(。你能帮忙吗?
  • @SergeiEensalu 你只需要为Navigator 创建包装器,这很简单
  • 感谢您的快速答复。我是 Flutter 的新手,你能举个例子吗? :)
  • @SergeiEensalu 这不是一个单行评论的事情;)将此作为一个单独的问题发布,也许我稍后会找时间回答
【解决方案3】:

广义的想法,您可以将控制器设为静态变量

class LoginController{
  final Function onContactingServerDone;
  LoginController({this.onContactingServerDone,});

  bool loggedIn;

  login()async {
    //contact server,get token or verify token etc

    onContactingServerDone();
  }
}

在你的屏幕上


LoginController _loginController;
initState(){
  _loginController = LoginController(onContactingServerDone: (){
    if(_loginController.loggedIn){
      Navigator.of(context).pushNamed('privateRoute');
    } else {
      Navigator.of(context).pushNamed('login');
    }
  },);
  _loginController.login();
}

Widget build(context){
  return CircularProgressIndicator();
}

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 2021-06-18
    • 2023-02-08
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多