首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Flutter中成功登录后返回app首页

如何在Flutter中成功登录后返回app首页
EN

Stack Overflow用户
提问于 2021-01-12 20:06:36
回答 1查看 1.1K关注 0票数 0

我正在尝试在我的Flutter应用程序中实现用户身份验证,该应用程序应该同时适用于Android和iOS。

我使用JWT来验证应用程序对服务器的请求,因此我在登录时为用户提供了一个JWT令牌,应用程序将令牌安全地保存在设备上,然后使用该令牌与服务器通信。

当应用程序启动时,我运行HomePage,其中有一条if语句,其中应用程序在安全存储中查找JWT令牌。如果没有令牌,应用程序将显示登录页面。

HomePage类:

代码语言:javascript
运行
复制
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.orange,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'App Title'),
      routes: <String, WidgetBuilder>{
        '/login': (BuildContext context) => new SignInPage(),
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ...
  @override
  Widget build(BuildContext context) {

    storage.read(key: 'jwt_token').then((token) {
      logger.d('MAIN APP GOT TOKEN: ' + token.toString());
      if (token == null) {
        Navigator.pushReplacementNamed(context, '/login');
      }
    });

    return Scaffold(...);
  }
}

我试过Navigator.pushReplacementNamedNavigator.pushNamedNavigator.popAndPushNamed...所有这些都会让我进入登录页面。所以这很好。我的问题是,反之亦然。

当我成功登录(获得JWT令牌)时,我无法使应用程序返回首页。如果我重新启动应用程序,它会正确地显示主页(因为现在安全存储中有一个JWT ),所以令牌检查工作正常。它必须是从登录页面重新路由到主页中的某些内容。

登录页面片段:

代码语言:javascript
运行
复制
if (serverResponse.containsKey('jwt_token')) {
    await storage.write(
         key: 'jwt_token', value: serverResponse['jwt_token']);
    Navigator.pushReplacementNamed(context, '/');

我还尝试了Navigator.popNavigator.pushNamed(context, '/')Navigator.pushNamedAndRemoveUntil(context, '/', (route) => false)Navigator.pushReplacementNamed(context, '/'),但都不起作用。

看起来页面正在改变,但它最终又变成了登录页面。当调用rerouting命令时,我检查了令牌已经在存储中。此外,我在HomePage中的令牌检查上方有一条调试消息,并且在登录后不会打印调试字符串,因此根本不会调用主页。

你在我的代码中发现了什么错误吗?我怎么才能让它工作呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-12 20:51:03

这里的问题是您正在检查主页build上的令牌。因此,每次启动屏幕时,当用户未登录时,它都会被正确地重定向到登录页面。

但是,由于您已经使用了Navigator.pushReplacementNamed,它将从您的路由列表中删除home,因此如果您尝试使用任何选项来移回路由列表,就像使用Navigator.pop一样,路由列表上将不再有home。

因此,根据您想要的行为,您基本上有两个选项需要处理:

1.默认登录页面

这是我在实践中看到的最常见的方法,在这种情况下,您的第一个应用程序屏幕是登录屏幕,因此只需在登录成功后使用Navigator.pushReplacementNamed发送到/home,将登录替换为主页,并提供通过Logout功能返回登录屏幕的方法。

2.重构用于令牌检查的登录

我建议使用initState来检查会话并重定向,而不是在build上使用检查,这样您就可以使用更简洁的生命周期进行重定向。只有一件事我不明白,那就是你没有在你的/路由中定义。尽管它们看起来是一样的,但我已经看到了一些与此相关的问题,因为home定义了应用程序启动的视图,而/定义了路由映射,所以为了以防万一,我也试着删除其他变量,如果是这样的话(我个人只使用命名路由,以使用户被发送到哪里的代码更加清晰)。

遵循一个使用Option 1的示例,但使用使用initStateOption 2上的建议

代码语言:javascript
运行
复制
class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  void checkPreviousSessionAndRedirect() async {
    String loginToken = await LocalDb.getAttribute('loginToken');
    if (loginToken != null) {
      Navigator.pushNamedAndRemoveUntil(
          context, RouteViews.MAIN, (Route<dynamic> route) => false);
    }
  }

  void initState() {
    super.initState();
    checkPreviousSessionAndRedirect();
  }
...

希望这会有帮助,如果没有帮助,请让我知道你有任何问题/问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65683630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档