Files
Holzleitner-Lieferservice-App/lib/data/network/holzleitner_auth_interceptor.dart
Dennis Nemec 7cf17466b3 fix(auth): Session ueberlebt Netz-Aussetzer; Zahlungsmethoden laden nach Re-Login neu
Kunde meldete haeufig 'Sitzung abgelaufen' und danach dauerhaft rotes
'Sitzung abgelaufen' bei den Zahlungsmethoden trotz erfolgreichem Login.

Token-Refresh:
- _performRefresh wertete JEDEN Fehler als tote Session (Logout + Refresh-
  Token geloescht) - auch Mobilfunk-/VPN-Aussetzer. Jetzt gilt nur noch eine
  echte Ablehnung durch Keycloak (OAuth invalid_grant o. ae.) als abgelaufen;
  voruebergehende Fehler behalten die Session, nutzen den noch gueltigen
  Access-Token weiter oder werfen AuthTemporarilyUnavailableException
- Interceptor schickt Requests nicht mehr tokenlos weiter (ergab 401 ->
  irrefuehrendes 'Sitzung abgelaufen'), sondern bricht als Verbindungsfehler ab
- restoreSession verwirft den Refresh-Token bei fehlendem Netz nicht mehr

Zahlungsmethoden:
- Cubit lud nur einmal beim App-Start (vor dem Login -> 401) und blieb danach
  fuer immer im Fehlerzustand. Jetzt Reload bei jedem Wechsel auf Authenticated
- Fehlerkarte in der Uebersicht hat einen 'Erneut laden'-Button

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 11:59:56 +03:00

48 lines
1.7 KiB
Dart

import 'package:dio/dio.dart';
import 'auth_token_provider.dart';
/// Dio-Interceptor, der pro Request den aktuellen Access-Token vom
/// `AuthTokenProvider` zieht und als `Authorization: Bearer …`-Header
/// anhängt. Provider-Fehler werden geloggt, der Request läuft trotzdem
/// weiter — das Backend antwortet dann mit 401, was der reguläre
/// Error-Handling-Pfad behandelt.
class HolzleitnerAuthInterceptor extends Interceptor {
HolzleitnerAuthInterceptor(this._tokenProvider);
final AuthTokenProvider _tokenProvider;
@override
Future<void> onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
try {
final token = await _tokenProvider.currentAccessToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
} on AuthTemporarilyUnavailableException catch (e) {
// Token ließ sich wegen eines Netz-/VPN-Problems nicht erneuern. NICHT
// tokenlos weiterschicken — das Backend würde mit 401 antworten und die
// UI fälschlich „Sitzung abgelaufen" zeigen. Stattdessen sauber als
// Verbindungsfehler abbrechen; der nächste Request versucht es erneut.
return handler.reject(
DioException(
requestOptions: options,
type: DioExceptionType.connectionError,
error: e,
message:
'Anmeldung konnte nicht erneuert werden (keine Verbindung zum Login-Server)',
),
);
} catch (e, stack) {
// TODO Phase B: hier ein strukturiertes Logging-Framework
// einhängen statt print.
// ignore: avoid_print
print('[HolzleitnerAuthInterceptor] Token-Provider hat geworfen: $e\n$stack');
}
handler.next(options);
}
}