Flutter 安全存储更改路线

Posted

技术标签:

【中文标题】Flutter 安全存储更改路线【英文标题】:Flutter Secure Storage Change Route 【发布时间】:2021-04-30 09:30:27 【问题描述】:

我已经在我的颤振项目中成功实现了flutter_secure_storage,当用户写下他的电子邮件和密码时,它被存储了,但这是我不明白的事情。我应该如何根据用户是否已经登录来设置屏幕路由。如果是同一个用户,那么username和pass都存放在secure_storage中,我想让他直接去HomeScreen(),但是如果有新用户需要登录,那么secure_storage中没有数据,然后我希望他发送到LoginScreen()。到目前为止,我已经这样做了:

import 'dart:async';
import 'package:flutter/material.dart';
import 'login_screen.dart';
import 'home_screen.dart';
import 'components/alarm_buttons.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class WelcomeScreen extends StatefulWidget 
  static const String id = 'welcome_screen';
  @override
  _WelcomeScreenState createState() => _WelcomeScreenState();


class _WelcomeScreenState extends State<WelcomeScreen> 
  void readData() async 
    final storage = FlutterSecureStorage();
    String myPassword = await storage.read(key: "p");
    String myEmail = await storage.read(key: "e");
    print(myEmail);
    print(myPassword);
  

  @override
  void initState() 
    final storage = FlutterSecureStorage();
    Timer(
        Duration(seconds: 2),
        () => Navigator.pushNamed(
              context,
              storage == null ? LoginScreen.id : HomePage.id,
            ));
    readData();
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: EdgeInsets.symmetric(horizontal: 24.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            AlarmButtons(
              buttonColour: Colors.grey,
              buttonText: 'Log In',
              buttonTextColour: Colors.white,
              onButtonPress: () 
                Navigator.pushNamed(context, LoginScreen.id);
              ,
            ),
            AlarmButtons(
              buttonColour: Colors.white,
              buttonText: 'Sign up',
              buttonTextColour: Colors.grey,
              onButtonPress: () 
                Navigator.pushNamed(context, SignUpScreen.id);
              ,
            ),
          ],
        ),
      ),
    );
  


现在,当我想返回欢迎屏幕(如上所示我的应用程序的起始页面)时,问题就开始了,自然它再次触发了 initState,我又回到了HomePage()。我该如何处理,仅在应用启动时触发该 initState,因此在自动登录后我可以返回欢迎屏幕而不触发它?

提前致谢!

【问题讨论】:

【参考方案1】:

您应该首先启动类似 SplashScreen(或在您的情况下为 WelcomeScreen)的东西。在那里,您可以根据保存的数据决定要导航到哪个屏幕。示例:

class SplashScreen extends StatefulWidget 
  const SplashScreen(Key key) : super(key: key);

  @override
  _SplashScreenState createState() => _SplashScreenState();


class _SplashScreenState extends State<SplashScreen> 
  @override
  void initState() 
    _startApp();
    super.initState();
  

  Future<void> _startApp() async 
    final storage = FlutterSecureStorage();
    String myEmail = await storage.read(key: "e");
    if (myEmail == null) 
      // TODO Navigate to Login Screen
     else 
      // TODO Navigate to Home Screen
    
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Center(
        child: Text("Splashscreen"),
      ),
    );
  

【讨论】:

虽然你的解决方案可能更干净,但它的作用相同,如果我想在这种情况下返回 SplashScreen,它只是一遍又一遍地重新运行 initState 方法。或者您是否建议仅为此目的制作一个“空”小部件或运行_startApp() 方法?这是 Flutter 中的合法做法吗?感谢您的帮助! 它并不是一个真正的“空”小部件,因为它会在您的数据加载时显示(等待 storage.read(key: "e")),这将非常简短。因此,我建议使用类似闪屏之类的东西。如果您导航到您的屏幕,您应该使用 Navigator.replace。因此,您无法导航回该屏幕,并且不会再次调用 initState 方法 我已经尝试过你的解决方案,老实说效果很好,再次感谢您的帮助!

以上是关于Flutter 安全存储更改路线的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地更改 Flutter Android Studio 项目中的“lib”目录名称?

Flutter Navigator 路由总是“/”

如何在 Flutter 中实现音频流应用和安全存储

如何在 Flutter 中使用路由制作持久抽屉?

Flutter 2022 战略和路线解读与想法

Flutter:同时进行英雄过渡 + 小部件动画?