You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用flutter_secure_storage无法维持用户登录及展示用户信息

Flutter使用flutter_secure_storage维持登录状态及展示用户信息的修复方案

问题根源

  1. 启动页登录状态判断时机错误:HomePage的initState中,调用secureStorage.readSecureData是异步操作,但紧接着就调用checkIfLogged,此时finalName还未被赋值,导致每次启动都跳转到登录页。
  2. 仪表盘页面异步数据未正确处理:DashBoard中直接在build方法里异步读取数据,然后同步渲染,此时finalName还没拿到存储的值,所以无法正确展示用户名。
  3. 登录页未等待存储写入完成就跳转:登录按钮点击后,调用writeSecureData后立刻跳转,可能存储操作还未完成,导致下次启动读取不到数据。

修复后的代码

main.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_get_storage/services/Storage.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

import './login_page.dart';
import './dashboard_page.dart';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final SecureStorage secureStorage = SecureStorage();

  @override
  void initState() {
    super.initState();
    _checkLoginStatus();
  }

  // 等待读取存储完成后再判断跳转
  Future<void> _checkLoginStatus() async {
    String? finalName = await secureStorage.readSecureData('username');
    if (finalName != null) {
      Get.offAll(() => DashBoard());
    } else {
      Get.offAll(() => LoginPage());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      ),
    );
  }
}

Storage.dart(封装类无需修改)

import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class SecureStorage {
  final _storage = FlutterSecureStorage();

  Future writeSecureData(String key, String value) async {
    var writeData = await _storage.write(key: key, value: value);
    return writeData;
  }

  Future readSecureData(String key) async {
    var readData = await _storage.read(key: key);
    return readData;
  }

  Future deleteSecureData(String key) async {
    var deleteData = await _storage.delete(key: key);
    return deleteData;
  }
}

login_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_get_storage/services/Storage.dart';
import 'package:get/get.dart';

import './dashboard_page.dart';

class LoginPage extends StatelessWidget {
  final username_controller = TextEditingController();
  final password_controller = TextEditingController();

  final SecureStorage secureStorage = SecureStorage();

  final ButtonStyle style =
      ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Home Page"),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              "Login Form",
              style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: TextField(
                controller: username_controller,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'username',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: TextField(
                controller: password_controller,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Password',
                ),
              ),
            ),
            ElevatedButton(
              style: style,
              onPressed: () async {
                String username = username_controller.text;
                String password = password_controller.text;

                if (username.isNotEmpty && password.isNotEmpty) {
                  // 等待存储写入完成后再跳转
                  await secureStorage.writeSecureData('username', username);
                  Get.offAll(() => DashBoard());
                } else {
                  Get.snackbar("Error", "Please Enter Username & Password",
                      snackPosition: SnackPosition.BOTTOM);
                }
              },
              child: Text("Log-In"),
            )
          ],
        ),
      ),
    );
  }
}

dashboard_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_get_storage/services/Storage.dart';
import 'package:get/get.dart';

import './login_page.dart';

class DashBoard extends StatelessWidget {
  final SecureStorage secureStorage = SecureStorage();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dashboard"),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              "USER DATA",
              style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
            ),
            // 使用FutureBuilder异步获取并展示用户名
            FutureBuilder<String?>(
              future: secureStorage.readSecureData('username'),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return CircularProgressIndicator();
                } else {
                  return Text(
                    "name : ${snapshot.data ?? '未获取到用户信息'}",
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
                  );
                }
              },
            ),
            ElevatedButton(
              onPressed: () async {
                await secureStorage.deleteSecureData('username');
                Get.offAll(() => LoginPage());
              },
              child: Text("LOGOUT"),
            )
          ],
        ),
      ),
    );
  }
}

修复说明

  • 启动页:将登录状态判断逻辑封装到异步方法_checkLoginStatus中,等待读取存储完成后再执行跳转,确保拿到正确的用户状态。
  • 登录页:添加await等待存储写入完成后再跳转,避免存储未完成就跳转到仪表盘导致的状态不一致。
  • 仪表盘:使用FutureBuilder处理异步读取操作,等待数据返回后再渲染UI,确保用户名能正确展示。

内容的提问来源于stack exchange,提问作者Snehil Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:25:19