Wymyśliłem nowe rozwiązanie, które ma niewielki narzut, ale wydaje się działać tak daleko, jak prototyp. Jednym z założeń jest to, że jesteś w honorowym środowisku systemowym do logowania, chociaż można to dostosować, żądając ponownie hasła za każdym razem, gdy zmieniasz zakładki.
Użyj localStorage (lub odpowiednika) i zdarzenia magazynu HTML5, aby wykryć, kiedy nowa karta przeglądarki przełączyła aktywnego użytkownika. Kiedy tak się stanie, utwórz nakładkę ducha z komunikatem, że nie możesz używać bieżącego okna (lub w inny sposób tymczasowo wyłącz okno, możesz nie chcieć, aby było tak widoczne). Gdy okno odzyska fokus, wyślij rejestrację żądania AJAX użytkownik z powrotem w.
Jedno zastrzeżenie do tego podejścia: nie możesz mieć żadnych normalnych wywołań AJAX (tj. Tych, które zależą od twojej sesji) w oknie, które nie jest fokusem (np. Jeśli połączenie miało miejsce z opóźnieniem), chyba że wcześniej ręcznie wykonujesz wywołanie ponownego logowania AJAX. Tak naprawdę wszystko, co musisz zrobić, to najpierw sprawdzić funkcję AJAX, aby upewnić się, że localStorage.currently_logged_in_user_id === window.yourAppNameSpace.user_id, a jeśli nie, zaloguj się najpierw przez AJAX.
Innym są warunki wyścigu: jeśli możesz przełączyć okna na tyle szybko, aby zmylić to, możesz skończyć z sekwencją relogin1-> relogin2-> ajax1-> ajax2, z ajax1 tworzonym w niewłaściwej sesji. Aby obejść ten problem, należy wypychać żądania logowania AJAX do tablicy, a następnie przechowywać je w pamięci i przed wydaniem nowego żądania logowania przerwać wszystkie bieżące żądania.
Ostatnią rzeczą, na którą należy zwrócić uwagę, jest odświeżanie okien. Jeśli ktoś odświeży okno, gdy masz aktywne, ale nie ukończone żądanie logowania AJAX, zostanie ono odświeżone w imieniu niewłaściwej osoby. W takim przypadku możesz użyć niestandardowego zdarzenia beforeunload, aby ostrzec użytkownika o potencjalnym pomyłce i poprosić go o kliknięcie Anuluj, w międzyczasie ponownie wysyłając żądanie logowania AJAX. Wtedy jedynym sposobem, w jaki mogą to spartaczyć, jest kliknięcie OK przed zakończeniem żądania (lub przypadkowe naciśnięcie klawisza Enter / spacja, ponieważ OK jest - niestety w tym przypadku - domyślnym). Istnieją inne sposoby obsługi tego przypadku, takie jak wykrywanie naciśnięć F5 i Ctrl + R / Alt + R, które będą działać w większości przypadków, ale mogą zostać udaremnione przez rekonfigurację skrótów klawiaturowych użytkownika lub alternatywne użycie systemu operacyjnego. W rzeczywistości jest to jednak ostry przypadek, a najgorsze scenariusze nigdy nie są takie złe: w konfiguracji systemu honorowego byłbyś zalogowany jako niewłaściwa osoba (ale możesz to wyjaśnić, personalizując strony za pomocą kolorów, stylów, wyraźnie wyświetlanych nazw, itp.); w konfiguracji hasła obowiązek wylogowania lub udostępnienia sesji spoczywa na ostatniej osobie, która wprowadziła hasło, lub jeśli ta osoba jest faktycznie bieżącym użytkownikiem, nie ma naruszenia.
Ale w końcu masz aplikację z jednym użytkownikiem na kartę, która (miejmy nadzieję) działa tak, jak powinna, bez konieczności konfigurowania profili, używania IE lub przepisywania adresów URL. Upewnij się, że na każdej karcie jest oczywiste, kto jest zalogowany na tej karcie, chociaż ...