f3cc2dfc2d
1. 去 dev 旁路:删除 auth_screen.dart 中 test@pangolin.dev 预填 + devLogin 跳过后端分支,以及 auth_provider.dart 的 devLogin() 方法。 2. 修 keychain -34018(errSecMissingEntitlement): 在 DebugProfile.entitlements / Release.entitlements 中添加 keychain-access-groups($(AppIdentifierPrefix)com.pangolin.pangolinVpn), 使 flutter_secure_storage 的 Data Protection Keychain API 获得正确 entitlement。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
2.3 KiB
Dart
67 lines
2.3 KiB
Dart
// auth_provider.dart — 认证状态(JWT 令牌生命周期)
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../services/auth_api.dart';
|
|
import '../services/token_store.dart';
|
|
|
|
// ── 状态 ────────────────────────────────────────────────────────────
|
|
|
|
class AuthState {
|
|
const AuthState({this.accessToken, this.isLoading = false});
|
|
|
|
final String? accessToken;
|
|
final bool isLoading;
|
|
|
|
bool get isLoggedIn => accessToken != null && accessToken!.isNotEmpty;
|
|
|
|
AuthState copyWith({String? accessToken, bool? isLoading}) => AuthState(
|
|
accessToken: accessToken ?? this.accessToken,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
);
|
|
}
|
|
|
|
// ── 状态机 ───────────────────────────────────────────────────────────
|
|
|
|
class AuthNotifier extends StateNotifier<AuthState> {
|
|
AuthNotifier(this._store) : super(const AuthState(isLoading: true)) {
|
|
_loadFromStore();
|
|
}
|
|
|
|
final TokenStore _store;
|
|
|
|
Future<void> _loadFromStore() async {
|
|
try {
|
|
final token = await _store.loadAccessToken();
|
|
state = AuthState(accessToken: token);
|
|
} catch (_) {
|
|
// FlutterSecureStorage 在测试环境 / 未初始化时抛异常,视为未登录。
|
|
state = const AuthState();
|
|
}
|
|
}
|
|
|
|
/// 登录 / 注册成功后保存令牌。
|
|
Future<void> saveTokens(AuthTokens tokens) async {
|
|
await _store.saveTokens(
|
|
access: tokens.accessToken,
|
|
refresh: tokens.refreshToken,
|
|
);
|
|
state = AuthState(accessToken: tokens.accessToken);
|
|
}
|
|
|
|
/// 退出登录:清除本地令牌。
|
|
Future<void> logout() async {
|
|
await _store.clear();
|
|
state = const AuthState();
|
|
}
|
|
}
|
|
|
|
// ── Providers ────────────────────────────────────────────────────────
|
|
|
|
/// 可在测试中 override,注入 stub TokenStore(避免 FlutterSecureStorage 平台依赖)。
|
|
final tokenStoreProvider = Provider<TokenStore>((_) => const TokenStore());
|
|
|
|
final authProvider =
|
|
StateNotifierProvider<AuthNotifier, AuthState>(
|
|
(ref) => AuthNotifier(ref.watch(tokenStoreProvider)),
|
|
);
|