Flutter安全存储问题:无法读取或写入密钥和值



我正在使用此包在Flutter移动应用程序中存储一些登录凭据。我使用的版本是v5.0.2。我不确定我是否以正确的方式存储或读取了值。有人知道如何检查吗,或者我遗漏了什么或做错了什么。

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class SecureStorage {
final _storage = const FlutterSecureStorage();
Future<Map<String, String>> _readAll() async {
return await _storage.readAll(
iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
}
void deleteAll() async {
await _storage.deleteAll(
iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
_readAll();
}
Future<String?> readSecureData(String key) async {
return await _storage.read(key: key);
}
Future<void> deleteSecureData(String key) async {
return await _storage.delete(key: key);
}
void writeSecureData(String key, String value) async {
await _storage.write(
key: key,
value: value,
iOptions: _getIOSOptions(),
aOptions: _getAndroidOptions(),
);
}
IOSOptions _getIOSOptions() => const IOSOptions(
accessibility: IOSAccessibility.first_unlock,
);
AndroidOptions _getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
);
}
final secureStorage = SecureStorage();

这就是我所说的价值,

@override
void initState() {
Future.delayed(Duration.zero, () async {
final username = await secureStorage.readSecureData('username') ?? '';
final password = await secureStorage.readSecureData('password') ?? '';
setState(() {
_icNoController.text = username;
_passwordController.text = password;
});
});
super.initState();
}

这就是我存储值的方式,

await secureStorage.writeSecureData('username', username);
await secureStorage.writeSecureData('password', password);

我认为读写问题的原因可能是与使用aOptionsiOptions不一致

例如,您将aOptionsreadAll()deleateAll()write()方法一起使用,而不将其与read()delete()一起使用

因此,当您将数据写入安全存储时,在aOptions中使用encryptedSharedPreferences: true,时,您指定必须将此数据写入EncryptedSharedPreferences

但是,当您在没有再次提供aOptions的情况下读取数据时,您会尝试从默认的安全存储中读取,该存储不是您存储数据的EncryptedSharedPreferences。aOptions的例子适用于Android,我还没有在iOS上测试过这个库。

我已经为您清理了类:

class SecureStorage {
const _storage = FlutterSecureStorage();
Future<Map<String, String>> _readAll() async {
var map = <String, String>{};
try {
map = await _storage.readAll(
iOptions: _getIOSOptions(),
aOptions: _getAndroidOptions(),
);
} catch (e) {
print(e);
}
return map;
}
Future<void> deleteAll() async {
try {
await _storage.deleteAll(
iOptions: _getIOSOptions(),
aOptions: _getAndroidOptions(),
);
// _readAll();
} catch (e) {
print(e);
}
}
Future<String> readSecureData(String key) async {
String value = "";
try {
value = (await _storage.read(key: key)) ?? "";
} catch (e) {
print(e);
}
return value;
}
Future<void> deleteSecureData(String key) async {
try {
await _storage.delete(key: key);
} catch (e) {
print(e);
}
}
Future<void> writeSecureData(String key, String value) async {
try {
await _storage.write(
key: key,
value: value,
iOptions: _getIOSOptions(),
aOptions: _getAndroidOptions(),
);
} catch (e) {
print(e);
}
}
IOSOptions _getIOSOptions() => const IOSOptions(
accessibility: IOSAccessibility.first_unlock,
);
AndroidOptions _getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
);
}

当然,我使用的是Logger包,而不是print。我也不明白你为什么在deleteAll之后再做_readAll

答案

Q"我不确定我是否以正确的方式存储或读取了该值">

A。存储和读取值的正确方法是将它们封装在try-catch块中,如上面的代码所示。

Q"有人知道如何检查吗,或者我遗漏了什么或做错了什么">

A。请参阅上面的代码,了解如何以正确的方式进行操作,我个人认为这对我有效。

一旦您在getter中使用了const,我认为如果您只将const选项放入FlutterSecureStorage构造函数中,可能会更好,例如:

final _storage = const FlutterSecureStorage(
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);

最新更新