在Flutter中建立私人路线

时间:2020-07-28 07:47:22

标签: flutter dart flutter-redux

如何对我的私有路由进行包装,私有路由仅在获得用户授权时才导航到屏幕,否则重定向到登录名并在登录后返回到原始屏幕。 如何以一种通用的方式做到这一点,以便我可以在其他未来的“私人”屏幕上重用它?

3 个答案:

答案 0 :(得分:1)

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

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()
    }
  )
)

答案 1 :(得分:0)

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

使用块模式或块库进行更好的状态管理。 希望对您有帮助。

答案 2 :(得分:0)

一般性的想法,您可以将控制器设为静态变量

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