W aplikacji internetowej zaimplementowanej w Javie przy użyciu JSP i Servletów; jeśli przechowuję informacje w sesji użytkownika, informacje te są udostępniane ze wszystkich zakładek tej samej przeglądarki. Jak rozróżnić sesje w kartach przeglądarki? W tym przykładzie:
<%@page language="java"%>
<%
String user = request.getParameter("user");
user = (user == null ? (String)session.getAttribute("SESSIONS_USER") : user);
session.setAttribute("SESSIONS_USER",user);
%>
<html><head></head><body>
<%=user %>
<form method="post">
User:<input name="user" value="">
<input type="submit" value="send">
</form>
</body></html>
Skopiuj ten kod do strony jsp ( testpage.jsp
), wdróż ten plik w istniejącym kontekście aplikacji internetowej na serwerze (używam Apache Tomcat), następnie otwórz przeglądarkę (FF, IE7 lub Opera) używając poprawnego adresu URL ( localhost/context1/testpage.jsp
), wpisz swoje imię i nazwisko w polu wejściowym i prześlij formularz. Następnie otwórz nową kartę w tej samej przeglądarce, a wtedy możesz zobaczyć swoje imię (pobierz z sesji) na nowej karcie. Uważaj na pamięć podręczną przeglądarki, czasami wydaje się, że tak się nie dzieje, ale jest w pamięci podręcznej, odśwież drugą kartę.
Dzięki.
Odpowiedzi:
Możesz użyć HTML5 SessionStorage (window.sessionStorage). Wygenerujesz losowy identyfikator i zapiszesz w pamięci sesji na karcie przeglądarki. Wtedy każda karta przeglądarki ma swój własny identyfikator.
źródło
Musisz zdać sobie sprawę, że sesje po stronie serwera są sztucznym dodatkiem do HTTP. Ponieważ protokół HTTP jest bezstanowy, serwer musi w jakiś sposób rozpoznać, że żądanie należy do określonego użytkownika, którego zna i dla którego ma sesję. Można to zrobić na dwa sposoby:
Co ty właściwie próbujesz zrobić? Dlaczego chcesz, aby karty miały oddzielne sesje? Może jest sposób na osiągnięcie celu bez korzystania z sesji?
Edycja: do testowania można znaleźć inne rozwiązania (na przykład uruchamianie kilku instancji przeglądarki na oddzielnych maszynach wirtualnych). Jeśli jeden użytkownik musi działać w różnych rolach w tym samym czasie, wówczas koncepcja „roli” powinna być obsługiwana w aplikacji, tak aby jeden login mógł mieć kilka ról. Będziesz musiał zdecydować, czy to, używając przepisywania adresów URL, czy po prostu żyjąc w obecnej sytuacji, jest bardziej akceptowalne, ponieważ po prostu nie jest możliwe oddzielne obsługiwanie kart przeglądarki w sesjach opartych na plikach cookie.
źródło
Właściwość window.name Javascript jest jedyną rzeczą, która będzie trwała przez aktywność karty, ale może pozostać niezależna (zamiast guff adresu URL).
źródło
Nie powinieneś.Jeśli chcesz coś takiego zrobić, musisz albo zmusić użytkownika do korzystania z pojedynczej instancji twojej aplikacji, pisząc adresy URL w locie, użyj identycznego identyfikatora sesji (nie sessionid, to nie zadziała) id i podaj go w każdym adresie URL.
Nie wiem, dlaczego tego potrzebujesz, ale jeśli nie potrzebujesz stworzyć całkowicie bezużytecznej aplikacji, nie rób tego.
źródło
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ż ...
źródło
Mieliśmy ten problem i rozwiązaliśmy go bardzo łatwo. Mam na myśli łatwe, ponieważ nie wymaga programowania. Chcieliśmy pozwolić użytkownikowi zalogować się na wiele kont w tym samym oknie przeglądarki bez kolidowania sesji.
Tak więc rozwiązaniem były przypadkowe subdomeny.
Poprosiliśmy więc administratora systemu o skonfigurowanie certyfikatów SSL dla * .abc.com zamiast abc.com. Następnie, przy niewielkiej zmianie kodu, za każdym razem, gdy użytkownik próbuje się zalogować, jest logowany na karcie z losowym numerem subdomeny. więc każda karta może mieć swoją własną sesję niezależnie. Aby uniknąć konfliktów, opracowaliśmy liczbę losową przy użyciu skrótu lub md5 identyfikatora użytkownika.
źródło
Będę tu szczery. . . wszystko powyżej może, ale nie musi, być prawdą, ale wszystko wydaje się DUŻO zbyt skomplikowane lub nie dotyczy wiedzy, która karta jest używana po stronie serwera.
Czasami musimy zastosować brzytwę Ockhama.
Oto podejście Occam: (nie, nie jestem Occam, zmarł w 1347)
1) przypisz do swojej strony unikalny identyfikator przeglądarki podczas wczytywania. . . wtedy i tylko wtedy, gdy okno nie ma jeszcze identyfikatora (więc użyj prefiksu i wykrywania)
2) na każdej stronie, którą masz (użyj pliku globalnego lub czegoś podobnego), po prostu umieść kod w miejscu, aby wykryć zdarzenie fokusu i / lub zdarzenie najechania myszą. (W tej części użyję jquery, aby ułatwić pisanie kodu)
3) w funkcji fokusu (i / lub najechania myszą) ustaw plik cookie z plikiem window.name
4) odczytaj wartość pliku cookie ze swojego serwera, gdy chcesz odczytać / zapisać dane dotyczące karty.
Strona klienta:
po stronie serwera (C # - na przykład do celów)
Gotowe.
źródło
Możesz użyć przepisywania linków, aby dołączyć unikalny identyfikator do wszystkich swoich adresów URL, zaczynając od pojedynczej strony (np. Index.html / jsp / cokolwiek). Przeglądarka będzie używać tych samych plików cookie dla wszystkich Twoich kart, więc wszystko, co umieścisz w plikach cookie, nie będzie unikatowe.
źródło
Myślę, że prawdopodobnie chcesz zachować stan nawigacji między kartami, a nie konkretnie tworzyć pojedynczą sesję na kartę. Dokładnie to osiąga platforma Seam dzięki ich zakresowi / kontekstowi konwersacji. Ich implementacja polega na tym, że identyfikator konwersacji jest propagowany z każdym żądaniem i tworzy pojęcie konwersacji po stronie serwera, czyli coś, co znajduje się między sesją a żądaniem. Pozwala na kontrolę przepływu nawigacji i zarządzanie stanem.
Chociaż jest to głównie skierowane do JSF, spójrz i sprawdź, czy jest to coś, z czego możesz czerpać pomysły: http://docs.jboss.org/seam/latest/reference/en-US/html_single/#d0e3620
źródło
W javascript, w jaki sposób mogę jednoznacznie zidentyfikować jedno okno przeglądarki od drugiego, które znajdują się w tym samym pliku cookie sessionId
Zasadniczo użyj window.name. Jeśli nie jest ustawiona, ustaw ją na unikalną wartość i użyj jej. Będzie się różnił na kartach należących do tej samej sesji.
źródło
Innym działającym podejściem jest utworzenie unikalnego identyfikatora okna i przechowywanie tej wartości wraz z identyfikatorem sesji w tabeli bazy danych. Identyfikator okna, którego często używam, to liczba całkowita (teraz). Ta wartość jest tworzona, gdy okno jest otwierane i ponownie przypisywane do tego samego okna, jeśli okno jest odświeżane, ponownie ładowane lub przesyłane do siebie. Wartości okien (wejścia) są zapisywane w lokalnej tabeli za pomocą linku. Gdy wymagana jest wartość, jest pobierana z tabeli bazy danych na podstawie odsyłacza id okna / id sesji. Chociaż takie podejście wymaga lokalnej bazy danych, jest praktycznie niezawodne. Korzystanie z tabeli bazy danych było dla mnie łatwe, ale nie widzę powodu, dla którego tablice lokalne nie działałyby tak dobrze.
źródło
Niedawno opracowałem rozwiązanie tego problemu za pomocą plików cookie. Oto link do mojego rozwiązania. Dołączyłem również przykładowy kod rozwiązania wykorzystujący ASP.NET, powinieneś być w stanie dostosować go do JSP lub Servelets, jeśli potrzebujesz.
https://sites.google.com/site/sarittechworld/track-client-windows
źródło
Spring Session obsługuje wiele sesji w tej samej przeglądarce Obejrzyj przykłady i szczegóły implementacji http://docs.spring.io/spring-session/docs/current/reference/html5/guides/users.html
źródło
Uwaga: tutaj rozwiązanie należy wykonać na etapie projektowania aplikacji. Trudno byłoby to zaprojektować później.
Użyj ukrytego pola, aby przekazać identyfikator sesji .
Aby to działało, każda strona musi zawierać formularz:
Każda czynność po Twojej stronie, w tym nawigacja, odsyła formularz z powrotem (ustawiając
action
odpowiednio). W przypadku „niebezpiecznych” żądań możesz dołączyć inny parametr, na przykład zawierający wartość JSON przesyłanych danych:Ponieważ nie ma plików cookie, każda karta będzie niezależna i nie będzie miała wiedzy o innych sesjach w tej samej przeglądarce.
Wiele zalet, szczególnie jeśli chodzi o bezpieczeństwo:
Niektóre wady:
Więcej informacji tutaj .
źródło
Rozwiązałem to w następujący sposób:
tutaj kod:
Mam nadzieję, że ci pomogę
źródło
Czytałem ten post, ponieważ myślałem, że chcę zrobić to samo. Mam podobną sytuację w przypadku aplikacji, nad którą pracuję. I tak naprawdę to bardziej kwestia testowania niż praktyczności.
Po przeczytaniu tych odpowiedzi, zwłaszcza tych udzielonych przez Michaela Borgwardta, zdałem sobie sprawę z przepływu pracy, który musi istnieć:
To rozwiąże problem polegający na tym, że użytkownik widzi dane „innego użytkownika” w swojej sesji. Tak naprawdę nie widzą danych „innego użytkownika” w swojej sesji, tak naprawdę widzą dane z jedynej otwartej sesji. Oczywiście powoduje to pewne interesujące dane, ponieważ niektóre operacje nadpisują niektóre dane sesji, a inne nie, więc masz kombinację danych w tej jednej sesji.
Teraz, aby rozwiązać problem z testowaniem. Jedynym realnym podejściem byłoby wykorzystanie dyrektyw preprocesora w celu określenia, czy należy używać sesji bez plików cookie. Widzisz, budując w określonej konfiguracji dla określonego środowiska, jestem w stanie poczynić pewne założenia dotyczące środowiska i tego, do czego jest używane. To pozwoliłoby mi technicznie na zalogowanie dwóch użytkowników w tym samym czasie, a tester mógłby testować wiele scenariuszy z tej samej sesji przeglądarki bez wylogowywania się z żadnej z tych sesji serwera.
Jednak takie podejście ma poważne zastrzeżenia. Nie mniej ważny jest fakt, że to, co testuje tester, nie jest tym, co zostanie uruchomione w produkcji.
Więc myślę, że muszę powiedzieć, że to ostatecznie zły pomysł.
źródło
Przechowywanie znacznika czasu w window.sessionStorage, jeśli nie jest jeszcze ustawiony. Zapewni to unikalną wartość dla każdej karty (nawet jeśli adresy URL są takie same)
http://www.javascriptkit.com/javatutors/domstorage.shtml
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
Mam nadzieję że to pomoże.
źródło
Najprostszym sposobem na zróżnicowanie sesji na kartach przeglądarki jest zablokowanie określonej domenie ustawiania plików cookie. W ten sposób możesz mieć oddzielne sesje z oddzielnych kart. Powiedz, że nie zezwalasz na pliki cookie z tej domeny: www.xyz.com. Otwierasz kartę 1, logujesz się i zaczynasz przeglądać. Następnie otwierasz kartę 2 i możesz zalogować się jako ten sam użytkownik lub inny; tak czy inaczej, sesja będzie oddzielona od karty 1. I tak dalej.
Ale oczywiście jest to możliwe, gdy masz kontrolę nad klientem. W przeciwnym razie zastosowanie powinny mieć rozwiązania zalecane przez ludzi tutaj.
źródło
będziesz musiał zrobić
1- zapisz plik cookie dla listy kont
2- Opcjonalnie przechowuj plik cookie jako domyślny
3- sklep dla każdego konta z jego indeksem, takim jak acc1, acc2
4- Wpisz w adresie URL coś, co reprezentuje indeks kont, a jeśli nie, wybierzesz domyślny, taki jak google mail domain.com/0/some-url >> 0 tutaj reprezentuje indeks konta również możesz potrzebować wiedzieć jak użyj urlwrite
5- kiedy wybierzesz plik cookie, wybierz go zgodnie ze ścieżką URL reprezentującą indeks konta
pozdrowienia
źródło
Widzę wiele implementacji, które mają zmiany po stronie klienta, aby manipulować plikami cookie identyfikatora sesji. Ale ogólnie pliki cookie z identyfikatorem sesji powinny być HttpOnly, więc skrypt java nie może uzyskać dostępu, w przeciwnym razie może to doprowadzić do przejęcia sesji przez XSS
źródło
Jeśli dzieje się tak dlatego, że każda karta będzie uruchamiać inny przepływ w Twojej aplikacji, a mieszanie obu przepływów powoduje problemy, lepiej „regionalizuj” obiekty sesji, aby każdy przepływ używał innego regionu sesji
Ten region można zaimplementować tak prosto, jak posiadanie różnych prefiksów dla każdego przepływu lub obiekt sesji będzie zawierał wiele map (po jednej dla każdego przepływu) i używasz tych map zamiast atrybutów sesji, najlepiej jednak byłoby rozszerzyć klasę sesji i użyj go zamiast tego.
źródło