Cha*_*acl 7 routes flutter flutter-web
我正在尝试在 Flutter 中创建一个网络应用程序,理想情况下它可以像网站一样工作。用户将登录并能够查看包含私人信息的仪表板,但某些屏幕上包含公共信息,任何人都可以使用动态路由 URL 导航到这些信息,例如: ,myflutterapp.com/feed/usersPublicInfo该链接可以发布到另一个网站,例如用户可以直接进入该路线。
显然,使用命名路由是我需要的解决方案,但是是什么阻止某人直接访问包含私人信息的路由呢?或者至少防止用户进入包含null信息的页面并导致小部件崩溃?
解决思路1
使用命名路由,并在登录屏幕之后将用户变量传递到每个屏幕,并在生成路由之前进行空检查。如果为空,则意味着有人跳过了一些路线,并且他们被发送回登录
解决思路2
如果可能,请混合使用命名路由和“未命名”路由,例如提要、仪表板和登录屏幕。用户进入仪表板后,所有路由都将使用 Navigator.push() 进行处理,从而防止从 URL 访问它们
其他解决方案?
我对 flutter 和 flutter web 相当陌生,所以我可能会完全错误地解决这个问题。我希望得到一些建议。谢谢!
static Future<void> init() async {
WidgetsFlutterBinding.ensureInitialized();
if(kIsWeb) {
final String defaultRouteName = WidgetsBinding.instance.window.defaultRouteName;
if(!(defaultRouteName == 'home' || defaultRouteName == 'login' || defaultRouteName == '/')) {
SystemNavigator.routeUpdated(
routeName: '/',
previousRouteName: null
);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
解决方案 1 对我来说看起来不错。
对于我的建议,使用Provider进行状态管理。这是我基于上下文的示例:
routes: {
"/": (context) => MainPage(),
"/detail": (context) => UserDetailPage(),
"/other": (context) => OtherPage(),
},
builder: (context, child) {
return Consumer<UsersProvider>(
child: child,
builder: (context, provider, child) {
if (provider.isLoading) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
final value = provider.user;
if (value == null) {
return Navigator(
onGenerateRoute: (settings) => MaterialPageRoute(
settings: settings, builder: (context) => LoginPage()),
);
}
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => UsersProvider()),
ChangeNotifierProvider(
create: (context) => InvoicesProvider()),
ChangeNotifierProvider(create: (context) => EventsProvider()),
],
child: child,
);
},
);
Run Code Online (Sandbox Code Playgroud)
基本上使用构建器并main.dart定义路由,然后在构建器内部使用 Consumer were child 是初始路由MainPage(),因此如果用户已经登录,他们将转到那里,如果没有,则基于我上下文中的标志,isAdmin他们将重定向到 LoginPage() 。因此,如果他们尝试使用 url 访问详细信息或其他内容,他们LoginPage无论如何都会重定向到。
这是我的用户提供者:
getUser() async {
FirebaseAuth.instance.onAuthStateChanged.listen((currentUser) async {
_isLoading = false;
if (currentUser == null) {
_user = null;
notifyListeners();
return;
}
final data = await Firestore.instance
.document("users/${currentUser.uid}")
.snapshots()
.first;
if (data.exists) {
print(data.data);
if (data.data['is_admin'] == true) {
_user = User.fromMap(data.data);
notifyListeners();
}
return null;
}
});
}
Run Code Online (Sandbox Code Playgroud)
所以如果用户isAdmin它会返回他们的值。我希望你能理解我的解释。我希望这对您也有帮助。