mirror of
https://github.com/chaos-zhu/easynode.git
synced 2026-10-07 16:18:31 +08:00
feat(mobile): 添加存储与 session cookie 持久化
- core/storage/app_storage.dart: shared_preferences 包装;保存 服务端地址、用户名与保存密码偏好。 - core/storage/secure_storage.dart: flutter_secure_storage 包装; 仅保存可选密码、token、session cookie 等高敏感数据。 - core/api/cookie_store.dart: 从 Set-Cookie 中提取 session=... 并写入 secure storage,请求时再回填到 Cookie header。
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import '../storage/secure_storage.dart';
|
||||
|
||||
/// Persists the EasyNode `session` cookie in secure storage and rehydrates
|
||||
/// it on every request. The cookie is the second half of EasyNode's auth
|
||||
/// pair (token header + session cookie), so it must survive process restarts.
|
||||
class SessionCookieStore {
|
||||
SessionCookieStore(this._storage);
|
||||
final SecureAppStorage _storage;
|
||||
|
||||
/// Look for `session=...` inside a `Set-Cookie` header list and persist it.
|
||||
/// Other cookies are ignored; EasyNode does not use them.
|
||||
Future<void> saveFromSetCookieHeaders(List<String> headers) async {
|
||||
for (final header in headers) {
|
||||
final firstPart = header.split(';').first.trim();
|
||||
if (firstPart.startsWith('session=')) {
|
||||
await _storage.writeSessionCookie(firstPart);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> readCookieHeader() => _storage.readSessionCookie();
|
||||
Future<void> clear() => _storage.deleteSessionCookie();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Low-sensitivity persistence — server address, username, save-password
|
||||
/// preference. Stored in `SharedPreferences` because Android/iOS app sandboxes
|
||||
/// already isolate these values from other apps and the value of using
|
||||
/// hardware-backed storage is small here.
|
||||
class AppStorage {
|
||||
AppStorage(this._prefs);
|
||||
|
||||
final SharedPreferences _prefs;
|
||||
|
||||
static const _keyServerAddress = 'serverAddress';
|
||||
static const _keyUsername = 'username';
|
||||
static const _keySavePassword = 'savePassword';
|
||||
|
||||
String get serverAddress => _prefs.getString(_keyServerAddress) ?? '';
|
||||
Future<void> setServerAddress(String value) => _prefs.setString(_keyServerAddress, value);
|
||||
|
||||
String get username => _prefs.getString(_keyUsername) ?? '';
|
||||
Future<void> setUsername(String value) => _prefs.setString(_keyUsername, value);
|
||||
|
||||
bool get savePassword => _prefs.getBool(_keySavePassword) ?? false;
|
||||
Future<void> setSavePassword(bool value) => _prefs.setBool(_keySavePassword, value);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
/// Hardware-backed secret store (Keystore on Android, Keychain on iOS).
|
||||
/// Holds saved password (only when user opted in), login token, session
|
||||
/// cookie, and any other high-sensitivity material.
|
||||
class SecureAppStorage {
|
||||
SecureAppStorage(this._storage);
|
||||
final FlutterSecureStorage _storage;
|
||||
|
||||
String _passwordKey(String serverAddress, String username) =>
|
||||
'password:$serverAddress:$username';
|
||||
|
||||
Future<String?> readPassword(String serverAddress, String username) {
|
||||
return _storage.read(key: _passwordKey(serverAddress, username));
|
||||
}
|
||||
|
||||
Future<void> writePassword(String serverAddress, String username, String password) {
|
||||
return _storage.write(key: _passwordKey(serverAddress, username), value: password);
|
||||
}
|
||||
|
||||
Future<void> deletePassword(String serverAddress, String username) {
|
||||
return _storage.delete(key: _passwordKey(serverAddress, username));
|
||||
}
|
||||
|
||||
Future<String?> readToken() => _storage.read(key: 'token');
|
||||
Future<void> writeToken(String token) => _storage.write(key: 'token', value: token);
|
||||
Future<void> deleteToken() => _storage.delete(key: 'token');
|
||||
|
||||
Future<String?> readSessionCookie() => _storage.read(key: 'sessionCookie');
|
||||
Future<void> writeSessionCookie(String value) =>
|
||||
_storage.write(key: 'sessionCookie', value: value);
|
||||
Future<void> deleteSessionCookie() => _storage.delete(key: 'sessionCookie');
|
||||
}
|
||||
Reference in New Issue
Block a user