Reputation: 362
I am using this package to store some login credentials in a Flutter mobile application. The version I use is v5.0.2. I am not sure if I am storing or reading the value in the correct way. Does anyone know how to check it, or what am I missing or doing wrong.
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();
This is how I called the value,
@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();
}
And this is how I stored the value,
await secureStorage.writeSecureData('username', username);
await secureStorage.writeSecureData('password', password);
Upvotes: 3
Views: 15504
Reputation: 21
Once you are using const
in your getters, I think maybe it will be better if you just throw the const options into the FlutterSecureStorage
constructor , like:
final _storage = const FlutterSecureStorage(
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
Upvotes: 2
Reputation: 138
I think the reason for reading / writing problem can be inconsistency with using aOptions
or iOptions
.
For ex. you are using aOptions
with readAll()
, deleateAll()
and write()
methods and you don't use it with read()
, delete()
.
So, when using encryptedSharedPreferences: true,
in aOptions
when you write data to secure storage, you specify that this data must be written to EncryptedSharedPreferences
.
However when you read the data without providing aOptions again, you try to read from default secure storage which is not the EncryptedSharedPreferences where you have stored the data.
Example with aOptions
is for Android, I haven't tested this library on iOS yet.
Upvotes: 6
Reputation: 1336
I have cleaned up the class for you:
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,
);
}
Of course, I use a Logger
package instead of print
. Also I don't understand why you do a _readAll
after deleteAll
.
ANSWERS
Q. "I am not sure if I am storing or reading the value in the correct way."
A. The correct way to store and read the values are by wrapping them in a try-catch
block, as illustrated the code above.
Q. "Does anyone know how to check it, or what am I missing or doing wrong."
A. See the code above for example of how to do it the right way which I personally found works for me.
Upvotes: 1