Microsoft-Login auf Redirect statt Popup umgestellt (Handy/Tablet-Fix)
Der Popup-basierte Login/Logout und die stille Token-Erneuerung per Hintergrund-iFrame sind in installierten PWAs auf iOS/Android unzuverlässig - Popups werden blockiert oder verlieren die Verbindung zum öffnenden Fenster, und iOS' ITP blockiert oft den iFrame-Speicherzugriff für die stille Erneuerung. Das zwang Monteure am Handy/Tablet zu ständigen Neuanmeldungen, während es am PC funktionierte. Login/Logout laufen jetzt über einen vollen Redirect, scheiternde stille Token-Erneuerung fällt sauber auf einen Redirect zurück statt mit einem Fehler abzubrechen, und storeAuthStateInCookie ist aktiviert (Microsofts eigene Empfehlung für Safari/iOS). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b591991d19
commit
3a82a22135
@@ -18,7 +18,11 @@ export default function Header({ localUser, onLocalLogout }: { localUser: string
|
||||
const [themeMode, setThemeMode] = useState<ThemeMode>(getStoredTheme());
|
||||
|
||||
function logout() {
|
||||
if (account) instance.logoutPopup();
|
||||
if (account) {
|
||||
// Redirect statt Popup, aus demselben Grund wie beim Login (siehe Login.tsx).
|
||||
instance.logoutRedirect();
|
||||
return;
|
||||
}
|
||||
onLocalLogout();
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -9,8 +9,17 @@ async function authHeader(): Promise<HeadersInit> {
|
||||
}
|
||||
const account = msalInstance.getAllAccounts()[0];
|
||||
if (!account) throw new Error('Nicht angemeldet.');
|
||||
const result = await msalInstance.acquireTokenSilent({ scopes: ['openid', 'profile'], account });
|
||||
return { Authorization: `Bearer ${result.idToken}`, 'Content-Type': 'application/json' };
|
||||
try {
|
||||
const result = await msalInstance.acquireTokenSilent({ scopes: ['openid', 'profile'], account });
|
||||
return { Authorization: `Bearer ${result.idToken}`, 'Content-Type': 'application/json' };
|
||||
} catch {
|
||||
// Silent Renewal (per Hintergrund-iFrame) scheitert auf iOS/Safari häufig, weil ITP
|
||||
// Drittanbieter-Speicherzugriff im iFrame blockiert. Statt mit einem kryptischen
|
||||
// Fehler abzubrechen, sauber per Redirect neu anmelden – der Nutzer landet danach
|
||||
// wieder genau hier.
|
||||
await msalInstance.acquireTokenRedirect({ scopes: ['openid', 'profile'], account });
|
||||
throw new Error('Anmeldung wird erneuert …');
|
||||
}
|
||||
}
|
||||
|
||||
async function req<T>(url: string, init?: RequestInit): Promise<T> {
|
||||
|
||||
@@ -14,7 +14,11 @@ const msalConfig: Configuration = {
|
||||
cache: {
|
||||
// localStorage statt sessionStorage: bleibt erhalten, wenn die (installierte) App
|
||||
// geschlossen und neu gestartet wird – sonst müsste man sich jedes Mal neu anmelden.
|
||||
cacheLocation: 'localStorage'
|
||||
cacheLocation: 'localStorage',
|
||||
// Von Microsoft explizit für Safari/iOS empfohlen: hält den Auth-State zusätzlich
|
||||
// in einem Cookie, da Safaris ITP die interne Silent-Renewal-/Redirect-Logik sonst
|
||||
// gerne stört – genau das Symptom "am Handy ständig neu anmelden müssen".
|
||||
storeAuthStateInCookie: true
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+7
-1
@@ -8,7 +8,13 @@ import './styles.css';
|
||||
|
||||
initTheme();
|
||||
|
||||
msalInstance.initialize().then(() => {
|
||||
msalInstance.initialize().then(() =>
|
||||
// Verarbeitet die Rückkehr von loginRedirect() (Popups sind in installierten PWAs auf
|
||||
// Handys/Tablets unzuverlässig – deshalb nutzt der Microsoft-Login einen vollen
|
||||
// Redirect statt eines Popups, siehe Login.tsx).
|
||||
msalInstance.handleRedirectPromise()
|
||||
).then(result => {
|
||||
if (result?.account) msalInstance.setActiveAccount(result.account);
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
<MsalProvider instance={msalInstance}>
|
||||
|
||||
@@ -14,11 +14,14 @@ export default function Login({ onLocalLogin }: { onLocalLogin: (name: string) =
|
||||
setBusy(true);
|
||||
setErr('');
|
||||
try {
|
||||
await instance.loginPopup({ scopes: ['openid', 'profile'] });
|
||||
// Redirect statt Popup: Popups werden in installierten PWAs auf Handys/Tablets
|
||||
// (Homescreen-App) von iOS/Android oft blockiert oder verlieren die Verbindung
|
||||
// zum öffnenden Fenster – dadurch musste man sich dort ständig neu anmelden.
|
||||
await instance.loginRedirect({ scopes: ['openid', 'profile'] });
|
||||
} catch (e) {
|
||||
setErr(e instanceof Error ? e.message : String(e));
|
||||
setBusy(false);
|
||||
}
|
||||
setBusy(false);
|
||||
}
|
||||
|
||||
async function submitLocal(e: FormEvent) {
|
||||
|
||||
Reference in New Issue
Block a user