在Angular中,可以使用canActivate
进行路由保护。
在Flutter,人们会怎么做?警卫在哪里?你如何守卫路线?
我是这样想的:
我也在这个问题上跌跌撞撞,最终为此使用了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
函数中执行逻辑,或者使用MaterialApp
的onGenerateRoute
属性。在您的情况下,一种方法是等待一个异步函数,该函数在加载初始路由之前检查用户是否登录。类似
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,
);
}
}
如果您不希望他们在登录时看到登录页面,请使用第一种方法,您可以通过探索此答案来控制runApp
UI之前显示的启动屏幕。
您可以使用auto_route
扩展。这个扩展非常适合处理路由,并提供了使用保护
的好方法。请参阅留档:https://pub.dev/packages/auto_route#route-guards