提问者:小点点

Flutter中的路线卫士


在Angular中,可以使用canActivate进行路由保护。

在Flutter,人们会怎么做?警卫在哪里?你如何守卫路线?

我是这样想的:

  • 用户已登录。他们的令牌存储在共享偏好中(存储令牌的正确方式?)
  • 用户关闭了应用程序。
  • 用户再次打开应用程序。当应用程序启动时,它确定用户是否已登录(可能是检查存储中令牌的服务),然后
  • 如果登录,加载主页路由
  • 如果未登录,加载登录页面

共3个答案

匿名用户

我也在这个问题上跌跌撞撞,最终为此使用了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。

匿名用户

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

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

但您可能也对Shrine应用程序的操作方式感兴趣。无论如何,他们都将登录页面作为初始路由,如果用户已登录,则将其删除。这样,用户就可以看到登录页面,直到确定他们是否登录。我在下面包含了相关片段。

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

如果您不希望他们在登录时看到登录页面,请使用第一种方法,您可以通过探索此答案来控制runAppUI之前显示的启动屏幕。

匿名用户

您可以使用auto_route扩展。这个扩展非常适合处理路由,并提供了使用保护的好方法。请参阅留档:https://pub.dev/packages/auto_route#route-guards