使用flutter_secure_storage无法维持用户登录及展示用户信息
Flutter使用flutter_secure_storage维持登录状态及展示用户信息的修复方案
问题根源
- 启动页登录状态判断时机错误:
HomePage的initState中,调用secureStorage.readSecureData是异步操作,但紧接着就调用checkIfLogged,此时finalName还未被赋值,导致每次启动都跳转到登录页。 - 仪表盘页面异步数据未正确处理:
DashBoard中直接在build方法里异步读取数据,然后同步渲染,此时finalName还没拿到存储的值,所以无法正确展示用户名。 - 登录页未等待存储写入完成就跳转:登录按钮点击后,调用
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
相关产品推荐
相关产品推荐

