首页 文章

Flutter的护卫队

提问于
浏览
2

在Angular中,可以使用 canActivate 进行路径防护 .

在Flutter,怎么会这样呢?守卫在哪里?你怎么守卫路线?

我正在考虑这个问题:

  • 用户登录 . 他们的令牌存储在共享首选项中(存储令牌的正确方法?)

  • 用户关闭了该应用 .

  • 用户再次打开应用程序 . 当应用程序启动时,它确定用户是否已登录(可能是检查存储的令牌的服务),然后

  • 如果已登录,请加载主页路由

  • 如果未登录,请加载登录页面

2 回答

  • 0

    我认为本身并没有路由保护机制,但您可以在加载应用程序之前在 main 函数中执行逻辑,或使用 MaterialApponGenerateRoute属性 . 在您的情况下执行此操作的一种方法是等待异步函数,该函数在加载初始路由之前检查用户是否已登录 . 就像是

    main() {
      fetchUser().then((user) {
        if (user != null) runApp(MyApp(page: 'home'));
        else runApp(MyApp(page: 'login'));
      });
    }
    

    但您可能也对Shrine应用程序的方式感兴趣 . 他们在任何情况下都将登录页面作为初始路由,并在用户登录时将其删除 . 这样用户就可以看到登录页面,直到确定他们是否登录 . 我已经在下面包含了relevant snippet .

    class ShrineApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Shrine',
          home: HomePage(),
          initialRoute: '/login',
          onGenerateRoute: _getRoute,
        );
      }
    
      Route<dynamic> _getRoute(RouteSettings settings) {
        if (settings.name != '/login') {
          return null;
        }
    
        return MaterialPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) => LoginPage(),
          fullscreenDialog: true,
        );
      }
    }
    

    如果您不希望他们在登录时完全看到登录页面,请使用第一种方法,您可以通过浏览this answer来控制在 runApp 拥有UI之前显示的初始屏幕 .

  • 2

    我也遇到了这个问题,最后使用了 FutureBuilder . 看看我的路线:

    final routes = {
      '/': (BuildContext context) => FutureBuilder<AuthState>(
        // This is my async call to sharedPrefs
        future: AuthProvider.of(context).authState$.skipWhile((_) => _ == null).first,
        builder: (BuildContext context, AsyncSnapshot<AuthState> snapshot) {
          switch(snapshot.connectionState) {
            case ConnectionState.done:
              // When the future is done I show either the LoginScreen 
              // or the requested Screen depending on AuthState
              return snapshot.data == AuthState.SIGNED_IN ? JobsScreen() : LoginScreen()
            default:
              // I return an empty Container as long as the Future is not resolved
              return Container();
          }
        },
      ),
    };
    

    如果要跨多个路由重用代码,可以扩展FutureBuilder .

相关问题