91 lines
2.6 KiB
Dart
91 lines
2.6 KiB
Dart
import 'package:shared_preferences/shared_preferences.dart';
|
|||
|
|
import '../../../core/constants/app_constants.dart';
|
||
|
|
|
||
|
|
/// Token 管理服务
|
||
|
|
/// 负责 Token 的存储、读取、刷新和清除
|
||
|
|
class TokenService {
|
||
|
|
static TokenService? _instance;
|
||
|
|
SharedPreferences? _prefs;
|
||
|
|
|
||
|
|
TokenService();
|
||
|
|
|
||
|
|
factory TokenService.getInstance() {
|
||
|
|
_instance ??= TokenService();
|
||
|
|
return _instance!;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<SharedPreferences> get _preferences async {
|
||
|
|
_prefs ??= await SharedPreferences.getInstance();
|
||
|
|
return _prefs!;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 获取 Access Token
|
||
|
|
Future<String?> getToken() async {
|
||
|
|
final prefs = await _preferences;
|
||
|
|
return prefs.getString(AppConstants.tokenKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 获取 Refresh Token
|
||
|
|
Future<String?> getRefreshToken() async {
|
||
|
|
final prefs = await _preferences;
|
||
|
|
return prefs.getString(AppConstants.refreshTokenKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 保存 Token
|
||
|
|
Future<void> saveTokens({
|
||
|
|
required String token,
|
||
|
|
String? refreshToken,
|
||
|
|
int? expiresIn,
|
||
|
|
}) async {
|
||
|
|
final prefs = await _preferences;
|
||
|
|
await prefs.setString(AppConstants.tokenKey, token);
|
||
|
|
if (refreshToken != null) {
|
||
|
|
await prefs.setString(AppConstants.refreshTokenKey, refreshToken);
|
||
|
|
}
|
||
|
|
if (expiresIn != null) {
|
||
|
|
final expiry = DateTime.now().millisecondsSinceEpoch + expiresIn * 1000;
|
||
|
|
await prefs.setInt(AppConstants.tokenExpiryKey, expiry);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 刷新 Token
|
||
|
|
Future<bool> refreshToken() async {
|
||
|
|
// TODO: 实现实际的 Token 刷新逻辑
|
||
|
|
// 使用 refreshToken 调用后端接口获取新的 accessToken
|
||
|
|
final refreshTok = await getRefreshToken();
|
||
|
|
if (refreshTok == null) return false;
|
||
|
|
|
||
|
|
try {
|
||
|
|
// 模拟刷新
|
||
|
|
// final response = await DioClient().post('/auth/refresh', data: {'refresh_token': refreshTok});
|
||
|
|
// await saveTokens(token: response.data['data']['token'], refreshToken: response.data['data']['refresh_token']);
|
||
|
|
return true;
|
||
|
|
} catch (e) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 检查 Token 是否过期
|
||
|
|
Future<bool> isTokenExpired() async {
|
||
|
|
final prefs = await _preferences;
|
||
|
|
final expiry = prefs.getInt(AppConstants.tokenExpiryKey);
|
||
|
|
if (expiry == null) return true;
|
||
|
|
return DateTime.now().millisecondsSinceEpoch > expiry;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 清除所有 Token
|
||
|
|
Future<void> clearTokens() async {
|
||
|
|
final prefs = await _preferences;
|
||
|
|
await prefs.remove(AppConstants.tokenKey);
|
||
|
|
await prefs.remove(AppConstants.refreshTokenKey);
|
||
|
|
await prefs.remove(AppConstants.tokenExpiryKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// 是否已登录
|
||
|
|
Future<bool> isLoggedIn() async {
|
||
|
|
final token = await getToken();
|
||
|
|
if (token == null) return false;
|
||
|
|
return !(await isTokenExpired());
|
||
|
|
}
|
||
|
|
}
|