Edge logt niet uit met sluiten van venster
Het gekke is dat de functie wel gewoon werkt met Internet Explorer en Firefox.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
window.addEventListener('unload', function() {
let oXhr = new XMLHttpRequest();
let sUrl = document.getElementById('xhrAfmelden').getAttribute('href');
oXhr.open('POST', sUrl, false); // sync, anders venter te vroeg gesloten
oXhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
formData.append('_CSRF_', sToken);
oXhr.send();
});
let oXhr = new XMLHttpRequest();
let sUrl = document.getElementById('xhrAfmelden').getAttribute('href');
oXhr.open('POST', sUrl, false); // sync, anders venter te vroeg gesloten
oXhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
formData.append('_CSRF_', sToken);
oXhr.send();
});
De code moet er voor zorgen dat wanneer een venster gesloten wordt, de gebruiker automatisch wordt uitgelogd.
Het is nodig omdat bijna geen enkele gebruiker zichzelf uitlogt.
Maar sinds kort verschijnt hierdoor in mijn JS-foutlog vanuit Edge deze melding:
Quote:
Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://www.<mijnsite>.nl/': Synchronous XHR in page dismissal. See https://www.chromestatus.com/feature/4664843055398912 for more details.
Het lijkt er op dat Edge (en evt. andere webkit browsers) de XMLHttpRequest niet afmaakt. Als ik de derde parameter van open() op true zet, werkt het soms wel met Edge, maar meestal niet. Wel krijg ik altijd de vraag van Edge 'Site opnieuw laden?.
Als ik het probeer met onbeforeunload gebeurt er helemaal niets, dus ik heb ff geen flauw idee hoe nu verder.
Weet iemand een oplossing?
https://www.chromestatus.com/feature/4664843055398912
Toevoeging op 22/06/2021 01:46:52:
Oooh ... zie nu dat dat gewoon de link is die in jouw post staat hahaha :D *facepalm*
Anyhow, lijkt dus by design te zijn.
"Chrome now disallows synchronous XHR during page dismissal when the page is being navigated away from or closed by the user."
Na wat zoekwerk blijkt dat de events onbeforeunload en unload onbetrouwbaar zijn, ofwel dat het niet overal goed werkt.
Volgens https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
Quote:
The beforeunload event suffers from the same problems as the unload event.
Especially on mobile, the beforeunload event is not reliably fired.
Especially on mobile, the beforeunload event is not reliably fired.
En bij de documentatie over unload staat:
Quote:
Developers should avoid using this event.
En bij de documentatie over XmlHttpRequest staat:
Quote:
synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.
Dus achteraf bezien was mijn oplossing van automatisch uitloggen bij het sluiten van de pagina al een tijdje gedeprecieerd, ook bij Firefox.
Kijkend naar een alternatief wordt via MDN verwezen naar de Page Lifecycle API bij Google, in het schema staan de pagehide en visibilitychange events als alternatief. Maar pagehide werkt in mijn geval ook niet in Edge. :-/
Dan zie ik nog maar een enkel alternatief, dat openstaande pagina's (gechecked via visibilitychange event) de sessie elke 5 minuten levend houden, gecombineerd met een verlooptijd voor sessies van 10 tot 15 minuten.
Gek genoeg had ik dit alternatief eerder juist vervangen voor automatisch uitloggen bij een beforeunload event, om veel onnodige HTTP-requests te voorkomen, maar kennelijk is dat juist weer geen probleem voor webkit.
Dus ik hoop vurig dat iemand nog een beter idee heeft?
Waarom moet een gebruiker trouwens automatisch worden uitgelogd? Bij inactiviteit verloopt toch zijn/haar sessie?
Edge bewaart de cookie netjes vanwege de Max-Age eigenschap. Maar het staat heel raar dat je nog bent ingelogd, wat als je even iemand anders achter je computer laat?
Toegegeven, ik heb het nagezocht in de ISO 27k en de NEN-7510, vanzelf uitloggen is geen verplichting.
Maar een gewonbe Fritz!Box doet het ook, dan moet het mij toch ook lukken...?
Edge bewaart de cookie netjes vanwege de Max-Age eigenschap.
Geldt dat ook voor een sessie-cookie? Ik kan het me haast niet voorstellen ...
Ik had ook Max-Age=0 kunnen doen, dan zou die moeten worden bewaard tot de browser sluit. Maar dan wordt die cookie ook niet eerder vanzelf opgeruimd.
Stel max-age gewoon eens niet in? Wat doet ie dan?
Ik zit nu op het spoor om de sessie ping maar weer in het leven te roepen, zodat je (eventueel) automatisch ingelogd blijft. Dat is zowieso nodig voor monitoring, je wilt ook niet dat ze elk kwartier ergens op moeten klikken.
En bij het sluiten van het venster mag een XmlHttpRequest misschien niet meer, maar ik kan dan misschien nog wel de cookie verwijderen.
Maar dit is normaal gedrag hoor ... als je een tab afsluit en de browser staat nog open, dan blijf je gewoon ingelogd. Als je de browser zelf afsluit, dan log je uit. Dit geldt uiteraard niet als je zelf op de 'uitloggen' link klikt.
>> Ik zit nu op het spoor om de sessie ping maar weer in het leven te roepen, zodat je (eventueel) automatisch ingelogd blijft.
Ik snap helemaal niet wat je hiermee bedoelt. Je kunt instellen hoe lang een SESSION in leven blijft. Als er in de tussentijd geen activiteit plaatsvindt, dan verloopt de sessie na die tijd en ben je dus uitgelogd.
Overigens, als ik bij de Fritz!Box de tab sluit en de browser niet, ben ik wel uitgelogd. Dat wil ik ook graag :-)
Doe iedere paar seconden een ajax check die de tijd wegschrijft... laat een cronjob lopen die iedere paar seconden checkt of de tijd nog actueel is (minder dan x seconden). Zo niet, log de betreffende user uit.
Gewijzigd op 22/06/2021 14:21:03 door Ozzie PHP
Helaas lukt het niet bij het sluiten van een tab om de HTTP cookie te verwijderen met JavaScript, omdat JS er niet bij mag... misschien moet ik sessie cookies maar helemaal afschaffen.
Toevoeging op 22/06/2021 15:18:37:
De reden dat JS er niet bij mag blijkt veiligheid, en dat is dus juist een reden om wél cookies te blijven gebruiken.
Maar het is toch wel een jungle, zonder standaard die alle browsers volgen.
Volgens MDN maakt het niet instellen van 'Expires' een cookie tot een sessie-cookie, die automatisch gesloten wordt als de browser gesloten wordt. Maar als ik alleen Max-Age instel, dan is het toch een sessie cookie maar wordt die niet door Edge gesloten bij het sluiten van de hele browser... en dat zuigt.
Max-Age=0 maakt dat de sessie cookie direct verloopt, dus de uitkomst is dat zowel Expires en Max-Age niet ingesteld moeten worden. Het enige nadeel is dat er een verouderde en dus ongeldige sessie ID in de browser bewaard blijft, daar moeten we maar mee leven.
Ik snap nog niet waarom je per se max-age instelt. Een sessie-cookie wordt verwijderd als je de browser sluit. Dat is toch wat je wil?
Daarnaast moet ik nog maken dat als een tab gesloten wordt, de sessie gesloten wordt.
En dat NPA's hun sessie blijven verlengen, met die andere truuk.
Toch blijf ik het interessant vinden dat het de Fritz!Box wel lukt... wat zie ik over het hoofd?
Wat is de Fritz!Box? Dat is toch een modem/router?
FritzBox interface is een SPA, en die begint gewoon altijd met dat loginscherm. Elke keer als je de pagina reload moet je weer inloggen. De sessie bestaat dus alleen in de JS context, en verloopt daarom zodra je de tab sluit (of ververst).
Ah oké ... maar dan is er eigenlijk geen sprake van een sessie, maar enkel van een login die je bij elke pagina verversing moet invoeren.
Die tokens moeten dan wel apart van de CSRF-tokes, anders kan er geen aparte melding komen wanneer met de UI gerommeld wordt.
Het voordeel is dat je op elke tab apart kan inloggen met een verschillende acount, waardoor je op 1 PC met een enkele browser kan werken.
Als er een extra scherm aanhangt voor monitoring, kan die een tab (in apart venster) tonen, die de monitoringspagina laat zien met een niet-persoonlijke account. Op je normale scherm kan je dan tegelijk met je persoonlijke account blijven werken. Top idee, al zegt ik het zelf.
Ik ben benieuwd. Het idee is wel grappig. Vraag me alleen af of als je dan met een sessie werkt, de ene tab niet de sessie van de andere tab overneemt. Wellicht moeten je sessie-cookies dan per tab een andere naam krijgen. Het is wel een hoop gedoe ... maar het houdt je van de straat zullen we maar zeggen ;-)
De beginpagina van de SPA verzint een ID voor de tab, dat wordt meegestuurd in alle XHR-verzoeken, waarmee de juiste cookie gekozen kan worden in PHP voor de sessies.
Open je een nieuwe tab of pagina? Dan krijg je een nieuw ID voor de tab, waarmee je niet bent ingelogd.
Nu nog maken dat sessies automatisch in leven gehouden worden.