Files
gamemanager/lib/services/auth_service.dart
T

71 lines
2.5 KiB
Dart

import 'package:flutter_appauth/flutter_appauth.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import '../config.dart';
/// Authentification OIDC pocket-id (Authorization Code + PKCE, client public).
/// Le jeton d'identité (JWT) est stocké de façon sécurisée et envoyé à l'API.
class AuthService {
final _appAuth = const FlutterAppAuth();
final _storage = const FlutterSecureStorage();
static const _kIdToken = 'id_token';
static const _kRefresh = 'refresh_token';
static const _kExpiry = 'access_expiry';
Future<String?> get idToken => _storage.read(key: _kIdToken);
Future<bool> isLoggedIn() async => (await idToken) != null;
Future<bool> login() async {
final result = await _appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
Config.oidcClientId,
Config.oidcRedirect,
issuer: Config.oidcIssuer,
scopes: Config.oidcScopes,
promptValues: ['login'],
),
);
if (result.idToken == null) return false;
await _storage.write(key: _kIdToken, value: result.idToken);
await _storage.write(key: _kRefresh, value: result.refreshToken);
await _storage.write(
key: _kExpiry,
value: result.accessTokenExpirationDateTime?.toIso8601String(),
);
return true;
}
/// Rafraîchit le jeton si expiré (via refresh_token), renvoie l'id_token courant.
Future<String?> validToken() async {
final expiry = await _storage.read(key: _kExpiry);
final refresh = await _storage.read(key: _kRefresh);
if (expiry != null && refresh != null) {
final exp = DateTime.tryParse(expiry);
if (exp != null && exp.isBefore(DateTime.now().add(const Duration(seconds: 30)))) {
try {
final r = await _appAuth.token(TokenRequest(
Config.oidcClientId,
Config.oidcRedirect,
issuer: Config.oidcIssuer,
refreshToken: refresh,
scopes: Config.oidcScopes,
));
if (r.idToken != null) {
await _storage.write(key: _kIdToken, value: r.idToken);
await _storage.write(key: _kRefresh, value: r.refreshToken ?? refresh);
await _storage.write(
key: _kExpiry,
value: r.accessTokenExpirationDateTime?.toIso8601String(),
);
}
} catch (_) {/* on garde l'ancien token, l'API renverra 401 si mort */}
}
}
return idToken;
}
Future<void> logout() async => _storage.deleteAll();
}