如何在Flutter不同页面安全访问SecureStorage中的Token?
问题解决与优化方案
一、当前错误的原因及修复
1. 首页"undefined name"错误原因
首页代码里的storage变量未定义、未实例化,且storage.read是异步方法,必须通过await获取结果。
2. 修复LoginResponseModel构造函数的语法错误
你的LoginResponseModel.fromJson中误用冒号(key:)而非赋值语句,导致类的key和non_field_errors属性未被正确赋值,修正后的代码如下:
LoginResponseModel.fromJson(mapOfBody) { key = mapOfBody['key']; non_field_errors = mapOfBody['non_field_errors']; print(mapOfBody['key']); // 创建存储实例并写入Token final storage = FlutterSecureStorage(); storage.write(key: 'Token', value: mapOfBody['key'].toString()); }
注意:将mapOfBody['key']转为String类型再存储,避免动态类型带来的潜在问题。
3. 首页正确访问Token的代码
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; Future<User> fetchUser() async { // 实例化存储对象 final storage = FlutterSecureStorage(); // 异步读取Token var token = await storage.read(key: 'Token'); var url = Uri.parse(Config.apiURL + Config.userProfileAPI); // 携带Token请求接口示例 var response = await http.get( url, headers: {'Authorization': 'Token $token'}, ); // 后续解析response生成User对象... }
二、更安全简便的实现方式
1. 封装单例Storage服务
创建storage_service.dart文件,统一封装Token的读写逻辑,避免重复实例化和代码冗余:
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class StorageService { static final StorageService _instance = StorageService._internal(); final FlutterSecureStorage _storage = const FlutterSecureStorage(); factory StorageService() => _instance; StorageService._internal(); // 存储Token Future<void> saveToken(String token) async { await _storage.write(key: 'Token', value: token); } // 获取Token Future<String?> getToken() async { return await _storage.read(key: 'Token'); } // 删除Token(登出时调用) Future<void> deleteToken() async { await _storage.delete(key: 'Token'); } }
2. 在LoginResponseModel中使用封装服务
LoginResponseModel.fromJson(mapOfBody) { key = mapOfBody['key']; non_field_errors = mapOfBody['non_field_errors']; print(mapOfBody['key']); // 调用单例服务存储Token StorageService().saveToken(mapOfBody['key'].toString()); }
3. 首页调用封装服务获取Token
Future<User> fetchUser() async { String? token = await StorageService().getToken(); var url = Uri.parse(Config.apiURL + Config.userProfileAPI); if (token != null) { var response = await http.get( url, headers: {'Authorization': 'Token $token'}, ); // 解析用户数据... } else { // 处理未登录场景,如跳转登录页 } }
4. 额外安全优化
- FlutterSecureStorage本身已基于Android Keystore、iOS Keychain实现安全存储,若需更高安全性,可在存储前对Token进行自定义加密。
- 结合状态管理(如Riverpod、Provider):将Token放入全局状态中,避免重复读取存储,同时实时监听Token变化(如登出时同步更新状态)。
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

