Introduction
The flutter_secure_storage Flutter package provides a simple, cross‑platform API for storing small, sensitive values—such as authentication tokens—in the native secure storage mechanisms of iOS (Keychain) and Android (Keystore). Because it abstracts the platform details, you can write one Dart API and let the plugin handle the rest.
When to Use flutter_secure_storage
- Storing API tokens, refresh tokens, or session identifiers.
- Saving user credentials that must survive app restarts.
- Any data that should be encrypted at rest and protected by the OS.
If you need to cache large blobs of data, images, or non‑sensitive preferences, consider shared_preferences or a file‑based solution instead.
Installation
Run the following command in your project root:
flutter pub add flutter_secure_storageAfter the package is added, run flutter pub get to fetch the dependencies.
Basic Usage Example
The following snippet demonstrates the most common workflow: write a token, read it back, and delete it when it’s no longer needed.
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// Create a storage instance. The default uses the platform's secure storage.
final FlutterSecureStorage secureStorage = const FlutterSecureStorage();
Future storeToken(String token) async {
// Write a value. The key is arbitrary but should be unique within your app.
await secureStorage.write(key: 'auth_token', value: token);
}
Future readToken() async {
// Read the stored value. Returns null if the key does not exist.
return await secureStorage.read(key: 'auth_token');
}
Future deleteToken() async {
// Remove the value from secure storage.
await secureStorage.delete(key: 'auth_token');
}
Future exampleFlow() async {
const String demoToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
await storeToken(demoToken);
final String? retrieved = await readToken();
print('Retrieved token: $retrieved');
await deleteToken();
}All methods are asynchronous because the underlying platform calls may involve I/O.
Advanced Options
You can customize the storage behavior with AndroidOptions and IOSOptions. For example, to enforce encrypted shared preferences on Android:
final AndroidOptions androidOptions = const AndroidOptions(
encryptedSharedPreferences: true,
);
final IOSOptions iosOptions = const IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
);
final FlutterSecureStorage customStorage = FlutterSecureStorage(
aOptions: androidOptions,
iOptions: iosOptions,
);These options are optional; the defaults work for most use‑cases.
Platform‑Specific Setup Notes
- iOS: No additional configuration is required for the basic API. If you need to adjust Keychain access groups, edit the
Runner/Info.plistas described in the plugin docs. - Android: The plugin works out‑of‑the‑box on API 18+. If you enable
encryptedSharedPreferences, ensure yourminSdkVersionis at least 23. - Web: The package does not support Flutter Web. Attempting to use it will throw a
UnsupportedError. Use a web‑specific secure storage solution instead.
⚠️ Always test secure storage on real devices (or emulators with the appropriate APIs) because simulator behavior can differ from production hardware.
Common Mistakes & How to Avoid Them
- Forgetting to await async calls: This can lead to race conditions where a token isn’t saved before you try to read it.
- Storing large blobs: The secure storage is optimized for small values (<~4 KB). Use the file system or a database for larger data.
- Hard‑coding keys: Keep your storage keys in a single constants file to avoid typos and make future refactors easier.
- Ignoring platform differences: Android and iOS may have different default encryption strengths. Verify the behavior on each platform if compliance matters.
- Not handling exceptions: Calls can fail (e.g., when the device is locked). Wrap reads/writes in try/catch and provide fallback logic.
FAQ
- Q: Can I use flutter_secure_storage on the web?
A: No. The package currently supports iOS, Android, macOS, Linux, and Windows. For web, consider using
flutter_web_secure_storageor encrypting data before storing it inlocalStorage. - Q: How does flutter_secure_storage differ from shared_preferences?
A:
shared_preferencesstores data in plain text files, suitable for non‑sensitive settings.flutter_secure_storageuses the OS‑level Keychain/Keystore, encrypting the data at rest. - Q: Do I need additional permissions on Android?
A: No extra manifest entries are required for the default Keystore usage. If you enable
encryptedSharedPreferences, the plugin adds the necessary dependencies automatically. - Q: How can I clear all stored values?
A: Call
await secureStorage.deleteAll();. This removes every key/value pair managed by the plugin. - Q: Is the data thread‑safe?
A: The plugin serializes calls internally, but it’s still best practice to await each operation rather than fire‑and‑forget.
Conclusion
The flutter_secure_storage Flutter package offers a straightforward, production‑ready way to keep tokens and other small secrets safe on mobile devices. By following the installation steps, respecting platform nuances, and avoiding common pitfalls, you can integrate secure storage into your FlutterFever apps with confidence.
For the latest details, always refer to the official package page on pub.dev.
Frequently Asked Questions
When should I choose flutter_secure_storage over shared_preferences?
Use flutter_secure_storage for any data that must be encrypted at rest, such as API tokens, refresh tokens, or user credentials. shared_preferences stores data in plain text and is intended for non‑sensitive preferences.
Does flutter_secure_storage work on Flutter Web?
No. The package does not support web platforms. For web, consider alternative solutions that encrypt data before using localStorage or sessionStorage.
How do I delete all stored keys at once?
Call the deleteAll method: <pre><code class="language-dart">await secureStorage.deleteAll();</code></pre>
Can I store binary data (e.g., images) with flutter_secure_storage?
The API accepts only string values. To store binary data, encode it (e.g., Base64) or use a different storage mechanism like the file system or a database.
What Android API level is required?
The default Keystore implementation works on API 18+. If you enable encryptedSharedPreferences, the minimum SDK should be 23.