125 lines
5.0 KiB
Dart
125 lines
5.0 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:local_auth/local_auth.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
class AuthService {
|
|
static final AuthService _instance = AuthService._internal();
|
|
static AuthService get instance => _instance;
|
|
AuthService._internal();
|
|
|
|
final _secureStorage = const FlutterSecureStorage(); // Per piattaforme mobili
|
|
// Non inizializzare SharedPreferences qui direttamente, perché è async
|
|
String? _token;
|
|
static const String _tokenKey = 'AuthToken'; // Chiave comune per storage
|
|
|
|
String? get token => _token;
|
|
// Questa funzione ora serve solo per la logica specifica mobile (es. biometrica)
|
|
// Non usarla per decidere dove salvare il token, usa kIsWeb direttamente
|
|
Future<bool> _isMobileOrDesktopPlatform() async {
|
|
if (kIsWeb) return false;
|
|
// Android, iOS, Windows, Linux, macOS
|
|
//final deviceInfo = DeviceInfoPlugin();
|
|
if (defaultTargetPlatform == TargetPlatform.android ||
|
|
defaultTargetPlatform == TargetPlatform.iOS ||
|
|
defaultTargetPlatform == TargetPlatform.windows ||
|
|
defaultTargetPlatform == TargetPlatform.linux ||
|
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Nuova funzione per salvare il token
|
|
Future<void> saveToken(String token) async {
|
|
_token = token; // Aggiorna il token in memoria
|
|
print('AuthToken: Tentativo di salvataggio token: $token');
|
|
|
|
if (kIsWeb) {
|
|
// Per Web: usa SharedPreferences (che su web usa localStorage)
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_tokenKey, token);
|
|
print('AuthToken: Token salvato in SharedPreferences (Web).');
|
|
} else if (await _isMobileOrDesktopPlatform()) {
|
|
// Per Mobile/Desktop: usa FlutterSecureStorage
|
|
await _secureStorage.write(key: _tokenKey, value: token);
|
|
print('AuthToken: Token salvato in FlutterSecureStorage (Mobile/Desktop).');
|
|
}
|
|
}
|
|
|
|
// Nuova funzione per caricare il token (senza biometria)
|
|
Future<String?> _loadTokenFromStorage() async {
|
|
if (kIsWeb) {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
return prefs.getString(_tokenKey);
|
|
} else if (await _isMobileOrDesktopPlatform()) {
|
|
return _secureStorage.read(key: _tokenKey);
|
|
}
|
|
return null; // Caso non supportato
|
|
}
|
|
|
|
|
|
Future<bool> loadTokenWithBiometric() async {
|
|
// Prima, prova sempre a caricare il token dallo storage generale
|
|
// Questo è il token che verra' utilizzato se la biometria fallisce o non è disponibile.
|
|
_token = await _loadTokenFromStorage();
|
|
if (_token != null && !await _isMobileOrDesktopPlatform()) {
|
|
// Se siamo su web e il token è stato caricato, l'autenticazione è implicita (no biometria)
|
|
print('AuthToken: Token caricato da storage (Web), biometria non applicabile.');
|
|
return true;
|
|
}
|
|
|
|
// Se non è una piattaforma mobile/desktop supportata per la biometria, o se il token non c'è,
|
|
// o se la biometria non è disponibile/non supportata, gestisci di conseguenza.
|
|
if (!await _isMobileOrDesktopPlatform()) {
|
|
print('AuthToken: Biometria non disponibile su questa piattaforma.');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
final auth = LocalAuthentication();
|
|
final canAuth = await auth.canCheckBiometrics || await auth.isDeviceSupported();
|
|
|
|
if (!canAuth) {
|
|
print('AuthToken: Dispositivo non supporta biometria.');
|
|
// Se la biometria non è supportata, ma un token esiste, consideralo loggato
|
|
return _token != null;
|
|
}
|
|
|
|
final authenticated = await auth.authenticate(
|
|
localizedReason: 'Autenticati per accedere',
|
|
options: const AuthenticationOptions(
|
|
biometricOnly: true,
|
|
stickyAuth: true,
|
|
),
|
|
);
|
|
|
|
if (authenticated) {
|
|
final stored = await _secureStorage.read(key: _tokenKey); // Rileggi da secure storage
|
|
_token = stored; // Aggiorna il token in memoria con quello autenticato biometricamente
|
|
print('AuthToken: Biometria riuscita, token da storage sicuro: $_token');
|
|
return stored != null;
|
|
} else {
|
|
print('AuthToken: Autenticazione biometrica fallita.');
|
|
_token = null; // Se la biometria fallisce, resetta il token in memoria
|
|
}
|
|
} catch (e) {
|
|
debugPrint('AuthToken: Errore autenticazione biometrica: $e');
|
|
_token = null; // In caso di errore, resetta il token
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Future<void> clear() async {
|
|
_token = null;
|
|
print('AuthToken: Tentativo di cancellazione token.');
|
|
if (kIsWeb) {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove(_tokenKey);
|
|
print('AuthToken: Token cancellato da SharedPreferences (Web).');
|
|
} else if (await _isMobileOrDesktopPlatform()) {
|
|
await _secureStorage.delete(key: _tokenKey);
|
|
print('AuthToken: Token cancellato da FlutterSecureStorage (Mobile/Desktop).');
|
|
}
|
|
}
|
|
} |