Skip to content

Flutter Secure Storage

Pour stocker des données sensibles comme les tokens d’authentification, mots de passe, clés API, utilisez Flutter Secure Storage qui chiffre les données.

dependencies:
flutter_secure_storage: ^9.0.0

Dans android/app/build.gradle :

android {
compileSdkVersion 33
// ...
}
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class SecureStorageService {
static const _storage = FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
),
iOptions: IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
),
);
// Sauvegarder des données sensibles
static Future<void> storeToken(String token) async {
await _storage.write(key: 'auth_token', value: token);
}
static Future<void> storeCredentials(String username, String password) async {
await _storage.write(key: 'username', value: username);
await _storage.write(key: 'password', value: password);
}
// Lire des données
static Future<String?> getToken() async {
return await _storage.read(key: 'auth_token');
}
static Future<Map<String, String?>>getCredentials() async {
final username = await _storage.read(key: 'username');
final password = await _storage.read(key: 'password');
return {'username': username, 'password': password};
}
// Supprimer des données
static Future<void> deleteToken() async {
await _storage.delete(key: 'auth_token');
}
static Future<void> deleteAll() async {
await _storage.deleteAll();
}
// Vérifier l'existence d'une clé
static Future<bool> hasToken() async {
return await _storage.containsKey(key: 'auth_token');
}
// Lister toutes les clés
static Future<Map<String, String>> getAllData() async {
return await _storage.readAll();
}
}
const AndroidOptions androidOptions = AndroidOptions(
encryptedSharedPreferences: true,
resetOnError: true,
sharedPreferencesName: 'secure_preferences',
preferencesKeyPrefix: 'flutter_secure_storage_',
);
const IOSOptions iosOptions = IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
groupId: 'group.com.example.app',
synchronizable: false,
accountName: 'FlutterSecureStorage',
);
  • first_unlock_this_device : Accessible après le premier déverrouillage
  • unlocked_this_device : Accessible seulement quand déverrouillé
  • first_unlock : Accessible après le premier déverrouillage (synchronisable)
  • unlocked : Accessible seulement quand déverrouillé (synchronisable)
class AuthStorageService {
static const _storage = FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
),
iOptions: IOSOptions(
accessibility: KeychainAccessibility.first_unlock_this_device,
),
);
static const String _accessTokenKey = 'access_token';
static const String _refreshTokenKey = 'refresh_token';
static const String _userIdKey = 'user_id';
// Sauvegarder les tokens d'authentification
static Future<void> saveAuthTokens({
required String accessToken,
required String refreshToken,
required String userId,
}) async {
await Future.wait([
_storage.write(key: _accessTokenKey, value: accessToken),
_storage.write(key: _refreshTokenKey, value: refreshToken),
_storage.write(key: _userIdKey, value: userId),
]);
}
// Récupérer les tokens
static Future<Map<String, String?>> getAuthTokens() async {
final results = await Future.wait([
_storage.read(key: _accessTokenKey),
_storage.read(key: _refreshTokenKey),
_storage.read(key: _userIdKey),
]);
return {
'accessToken': results[0],
'refreshToken': results[1],
'userId': results[2],
};
}
// Vérifier si l'utilisateur est connecté
static Future<bool> isLoggedIn() async {
final accessToken = await _storage.read(key: _accessTokenKey);
return accessToken != null && accessToken.isNotEmpty;
}
// Déconnexion - supprimer tous les tokens
static Future<void> logout() async {
await Future.wait([
_storage.delete(key: _accessTokenKey),
_storage.delete(key: _refreshTokenKey),
_storage.delete(key: _userIdKey),
]);
}
// Mettre à jour seulement l'access token
static Future<void> updateAccessToken(String newAccessToken) async {
await _storage.write(key: _accessTokenKey, value: newAccessToken);
}
}
class SecureStorageWrapper {
static const _storage = FlutterSecureStorage();
static Future<String?> readSafely(String key) async {
try {
return await _storage.read(key: key);
} catch (e) {
print('Erreur lors de la lecture de $key: $e');
return null;
}
}
static Future<bool> writeSafely(String key, String value) async {
try {
await _storage.write(key: key, value: value);
return true;
} catch (e) {
print('Erreur lors de l\'écriture de $key: $e');
return false;
}
}
static Future<bool> deleteSafely(String key) async {
try {
await _storage.delete(key: key);
return true;
} catch (e) {
print('Erreur lors de la suppression de $key: $e');
return false;
}
}
}
  1. Données sensibles uniquement : Ne stocker que les données réellement sensibles
  2. Rotation des tokens : Implémenter un système de rotation des tokens
  3. Expiration : Gérer l’expiration des données stockées
  4. Validation : Valider les données avant le stockage
  5. Nettoyage : Supprimer les données lors de la déconnexion
  6. Gestion d’erreurs : Toujours gérer les exceptions
  7. Tests : Tester sur différents appareils et versions d’OS
  • Tokens d’authentification : JWT, OAuth tokens, API keys
  • Identifiants de connexion : Mots de passe, biométrie
  • Clés de chiffrement : Clés AES, certificats
  • Données personnelles sensibles : Numéros de sécurité sociale, informations bancaires
  • Configuration sensible : URLs privées, secrets d’application
  • Performance : Plus lent que SharedPreferences
  • Taille : Limité à de petites quantités de données
  • Compatibilité : Vérifier les versions d’Android/iOS supportées
  • Backup : Les données peuvent être perdues lors de restaurations système