Flutter安全存储初始化插件flutter_secure_storage_with_init的使用
Flutter安全存储初始化插件flutter_secure_storage_with_init
的使用
flutter_secure_storage_with_init
是一个 Flutter 插件,用于在安全存储中存储数据。它在不同平台上使用不同的安全机制:
- 对于 iOS,使用
Keychain
。 - 对于 Android,使用 AES 加密,AES 密钥通过 RSA 加密,并将 RSA 密钥存储在
KeyStore
中。 - 对于 Linux,使用
libsecret
。
获取开始
首先,在你的 Dart 文件中导入 flutter_secure_storage_with_init
包:
import 'package:flutter_secure_storage/flutter_secure_storage_with_init.dart';
创建一个 FlutterSecureStorage
实例并使用以下方法进行操作:
// 创建存储实例
final storage = FlutterSecureStorageWithInit();
// 读取值
String value = await storage.read(key: key);
// 读取所有值
Map<String, String> allValues = await storage.readAll();
// 删除值
await storage.delete(key: key);
// 删除所有值
await storage.deleteAll();
// 写入值
await storage.write(key: key, value: value);
配置Android版本
确保你的 minSdkVersion
设置为 >= 18:
android {
...
defaultConfig {
...
minSdkVersion 18
...
}
}
注意:默认情况下,Android 会在 Google Drive 上备份数据,这可能会导致 java.security.InvalidKeyException: Failed to unwrap key
异常。你需要:
- 禁用自动备份:禁用自动备份。
- 排除共享偏好设置文件:排除共享偏好设置文件。
Linux
在构建项目时,需要安装 libsecret-1-dev
和 libjsoncpp-dev
。运行应用时,需要 libsecret-1-0
和 libjsoncpp1
。如果你使用 snapcraft
构建项目,可以使用以下配置:
parts:
uet-lms:
source: .
plugin: flutter
flutter-target: lib/main.dart
build-packages:
- libsecret-1-dev
- libjsoncpp-dev
stage-packages:
- libsecret-1-dev
- libjsoncpp1-dev
集成测试
从 example
目录运行以下命令:
flutter drive --target=test_driver/app.dart
完整示例代码
以下是完整的示例代码,展示了如何使用 flutter_secure_storage_with_init
插件:
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage_with_init.dart';
void main() {
runApp(MaterialApp(home: ItemsWidget()));
}
class ItemsWidget extends StatefulWidget {
[@override](/user/override)
_ItemsWidgetState createState() => _ItemsWidgetState();
}
enum _Actions { deleteAll }
enum _ItemActions { delete, edit }
class _ItemsWidgetState extends State<ItemsWidget> {
final _storage = FlutterSecureStorageWithInit();
final _accountNameController = TextEditingController(text: 'flutter_secure_storage_service');
List<_SecItem> _items = [];
[@override](/user/override)
void initState() {
super.initState();
_accountNameController.addListener(() => _readAll());
_readAll();
}
Future<void> _readAll() async {
final all = await _storage.readAll(
iOptions: _getIOSOptions(),
);
setState(() {
_items = all.entries
.map((entry) => _SecItem(entry.key, entry.value))
.toList(growable: false);
});
}
void _deleteAll() async {
await _storage.deleteAll(
iOptions: _getIOSOptions(),
);
_readAll();
}
void _addNewItem() async {
final String key = _randomValue();
final String value = _randomValue();
await _storage.write(
key: key,
value: value,
iOptions: _getIOSOptions(),
);
_readAll();
}
IOSOptions _getIOSOptions() => IOSOptions(
accountName: _getAccountName(),
);
String? _getAccountName() => _accountNameController.text.isEmpty ? null : _accountNameController.text;
[@override](/user/override)
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Plugin example app'),
actions: <Widget>[
IconButton(
key: Key('add_random'),
onPressed: _addNewItem,
icon: Icon(Icons.add)),
PopupMenuButton<_Actions>(
key: Key('popup_menu'),
onSelected: (action) {
switch (action) {
case _Actions.deleteAll:
_deleteAll();
break;
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<_Actions>>[
PopupMenuItem(
key: Key('delete_all'),
value: _Actions.deleteAll,
child: Text('Delete all'),
),
])
],
),
body: Column(
children: [
if (Platform.isIOS)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: TextFormField(
controller: _accountNameController,
decoration: InputDecoration(labelText: 'kSecAttrService'),
),
),
Expanded(
child: ListView.builder(
itemCount: _items.length,
itemBuilder: (BuildContext context, int index) => ListTile(
trailing: PopupMenuButton(
key: Key('popup_row_$index'),
onSelected: (_ItemActions action) => _performAction(action, _items[index]),
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<_ItemActions>>[
PopupMenuItem(
value: _ItemActions.delete,
child: Text(
'Delete',
key: Key('delete_row_$index'),
),
),
PopupMenuItem(
value: _ItemActions.edit,
child: Text(
'Edit',
key: Key('edit_row_$index'),
),
),
]),
title: Text(
_items[index].value,
key: Key('title_row_$index'),
),
subtitle: Text(
_items[index].key,
key: Key('subtitle_row_$index'),
),
),
),
),
],
),
);
Future<void> _performAction(_ItemActions action, _SecItem item) async {
switch (action) {
case _ItemActions.delete:
await _storage.delete(
key: item.key,
iOptions: _getIOSOptions(),
);
_readAll();
break;
case _ItemActions.edit:
final result = await showDialog<String>(
context: context,
builder: (context) => _EditItemWidget(item.value));
if (result != null) {
await _storage.write(
key: item.key,
value: result,
iOptions: _getIOSOptions(),
);
_readAll();
}
break;
}
}
String _randomValue() {
final rand = Random();
final codeUnits = List.generate(20, (index) {
return rand.nextInt(26) + 65;
});
return String.fromCharCodes(codeUnits);
}
}
class _EditItemWidget extends StatelessWidget {
_EditItemWidget(String text)
: _controller = TextEditingController(text: text);
final TextEditingController _controller;
[@override](/user/override)
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Edit item'),
content: TextField(
key: Key('title_field'),
controller: _controller,
autofocus: true,
),
actions: <Widget>[
TextButton(
key: Key('cancel'),
onPressed: () => Navigator.of(context).pop(),
child: Text('Cancel')),
TextButton(
key: Key('save'),
onPressed: () => Navigator.of(context).pop(_controller.text),
child: Text('Save')),
],
);
}
}
class _SecItem {
_SecItem(this.key, this.value);
final String key;
final String value;
}
更多关于Flutter安全存储初始化插件flutter_secure_storage_with_init的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter安全存储初始化插件flutter_secure_storage_with_init的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_secure_storage_with_init
是一个 Flutter 插件,它扩展了 flutter_secure_storage
插件,允许在初始化时设置一些默认选项。这个插件用于在 Flutter 应用中安全地存储敏感数据,如令牌、密码等。
安装
首先,你需要在 pubspec.yaml
文件中添加依赖:
dependencies:
flutter_secure_storage_with_init: ^1.0.0
然后运行 flutter pub get
来安装依赖。
使用
flutter_secure_storage_with_init
的使用方式与 flutter_secure_storage
类似,但在初始化时可以设置一些默认选项。
1. 初始化
在应用启动时,你可以初始化 FlutterSecureStorageWithInit
并设置一些默认选项:
import 'package:flutter_secure_storage_with_init/flutter_secure_storage_with_init.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化 FlutterSecureStorageWithInit
await FlutterSecureStorageWithInit.init(
androidOptions: AndroidOptions(encryptedSharedPreferences: true),
iosOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
);
runApp(MyApp());
}
2. 存储数据
你可以使用 FlutterSecureStorageWithInit
来存储敏感数据:
final storage = FlutterSecureStorageWithInit();
await storage.write(key: 'my_key', value: 'my_value');
3. 读取数据
你可以使用 FlutterSecureStorageWithInit
来读取存储的数据:
final storage = FlutterSecureStorageWithInit();
String? value = await storage.read(key: 'my_key');
print(value); // 输出: my_value
4. 删除数据
你可以使用 FlutterSecureStorageWithInit
来删除存储的数据:
final storage = FlutterSecureStorageWithInit();
await storage.delete(key: 'my_key');
5. 删除所有数据
你可以使用 FlutterSecureStorageWithInit
来删除所有存储的数据:
final storage = FlutterSecureStorageWithInit();
await storage.deleteAll();