In einer in Java implementierten Webanwendung mit JSP und Servlets; Wenn ich Informationen in der Benutzersitzung speichere, werden diese Informationen von allen Registerkarten desselben Browsers freigegeben. Wie können Sitzungen in den Browser-Registerkarten unterschieden werden? In diesem Beispiel:
<%@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>
Kopieren Sie diesen Code in eine JSP-Seite ( testpage.jsp
), stellen Sie diese Datei in einem vorhandenen Kontext einer Webanwendung auf dem Server bereit (ich verwende Apache Tomcat) und öffnen Sie dann einen Browser (FF, IE7 oder Opera) mit der richtigen URL ( localhost/context1/testpage.jsp
) Geben Sie Ihren Namen in die Eingabe ein und senden Sie das Formular ab. Öffnen Sie dann eine neue Registerkarte im selben Browser, und Sie können Ihren Namen (aus der Sitzung abrufen) auf der neuen Registerkarte sehen. Seien Sie vorsichtig mit dem Browser-Cache, manchmal scheint es nicht zu passieren, aber es ist im Cache, aktualisieren Sie die zweite Registerkarte.
Vielen Dank.
Antworten:
Sie können HTML5 SessionStorage (window.sessionStorage) verwenden. Sie generieren eine zufällige ID und speichern sie im Sitzungsspeicher pro Browser-Registerkarte. Dann hat jeder Browser-Tab seine eigene ID.
quelle
Sie müssen erkennen, dass serverseitige Sitzungen ein künstliches Add-On zu HTTP sind. Da HTTP zustandslos ist, muss der Server irgendwie erkennen, dass eine Anforderung einem bestimmten Benutzer gehört, den er kennt und für den er eine Sitzung hat. Es gibt zwei Möglichkeiten, dies zu tun:
Was versuchst du überhaupt zu tun? Warum sollten Registerkarten separate Sitzungen haben? Vielleicht gibt es eine Möglichkeit, Ihr Ziel zu erreichen, ohne überhaupt Sitzungen zu verwenden?
Bearbeiten: Zum Testen können andere Lösungen gefunden werden (z. B. das Ausführen mehrerer Browserinstanzen auf separaten VMs). Wenn ein Benutzer gleichzeitig in verschiedenen Rollen agieren muss, sollte das "Rollen" -Konzept in der App behandelt werden, damit ein Login mehrere Rollen haben kann. Sie müssen entscheiden, ob dies, das Umschreiben von URLs oder das einfache Leben mit der aktuellen Situation akzeptabler ist, da es einfach nicht möglich ist, Browser-Registerkarten mit Cookie-basierten Sitzungen separat zu behandeln.
quelle
Die Javascript-Eigenschaft window.name ist das einzige Element, das über die Tabulatoraktivität hinweg erhalten bleibt, jedoch unabhängig bleiben kann (anstelle von URL-Guff).
quelle
Das solltest du nicht.Wenn Sie so etwas tun möchten, müssen Sie den Benutzer zwingen, eine einzelne Instanz Ihrer Anwendung zu verwenden, indem Sie URLs im laufenden Betrieb schreiben. Verwenden Sie eine ID für die gleiche Sitzungs-ID (keine Sitzungs-ID, die nicht funktioniert) und übergeben Sie sie in jeder URL.
Ich weiß nicht, warum Sie es brauchen, aber wenn Sie keine völlig unbrauchbare Anwendung erstellen müssen, tun Sie es nicht.
quelle
Ich habe mir eine neue Lösung ausgedacht, die ein wenig Overhead hat, aber anscheinend als Prototyp funktioniert. Eine Annahme ist, dass Sie sich für die Anmeldung in einer Ehrensystemumgebung befinden. Dies kann jedoch angepasst werden, indem Sie beim Wechseln der Registerkarte erneut ein Kennwort anfordern.
Verwenden Sie localStorage (oder ein gleichwertiges Element) und das HTML5-Speicherereignis, um festzustellen, wann eine neue Browserregisterkarte gewechselt hat, welcher Benutzer aktiv ist. Erstellen Sie in diesem Fall ein Ghost-Overlay mit der Meldung, dass Sie das aktuelle Fenster nicht verwenden können (oder deaktivieren Sie das Fenster auf andere Weise vorübergehend, damit es nicht so auffällig wird.) Wenn das Fenster wieder den Fokus erhält, senden Sie eine AJAX-Anforderungsprotokollierung der Benutzer wieder in.
Eine Einschränkung dieses Ansatzes: Sie können keine normalen AJAX-Anrufe (dh solche, die von Ihrer Sitzung abhängen) in einem Fenster ausführen, das nicht den Fokus hat (z. B. wenn Sie einen Anruf nach einer Verzögerung hatten), es sei denn Sie führen zuvor manuell einen AJAX-Neuanmeldeanruf durch. Alles, was Sie wirklich tun müssen, ist, zuerst Ihre AJAX-Funktion überprüfen zu lassen, um sicherzustellen, dass localStorage.currently_logged_in_user_id === window.yourAppNameSpace.user_id. Wenn nicht, melden Sie sich zuerst über AJAX an.
Ein weiterer Grund sind die Rennbedingungen: Wenn Sie das Fenster schnell genug wechseln können, um es zu verwirren, erhalten Sie möglicherweise eine relogin1-> relogin2-> ajax1-> ajax2-Sequenz, wobei ajax1 in der falschen Sitzung erstellt wird. Umgehen Sie dies, indem Sie AJAX-Anmeldeanforderungen auf ein Array übertragen und dann speichern und vor dem Ausgeben einer neuen Anmeldeanforderung alle aktuellen Anforderungen abbrechen.
Das letzte Problem, auf das Sie achten müssen, sind Fensteraktualisierungen. Wenn jemand das Fenster aktualisiert, während eine AJAX-Anmeldeanforderung aktiv, aber nicht abgeschlossen ist, wird es im Namen der falschen Person aktualisiert. In diesem Fall können Sie das nicht standardmäßige Ereignis "Beforeunload" verwenden, um den Benutzer vor einer möglichen Verwechslung zu warnen und ihn aufzufordern, auf "Abbrechen" zu klicken, während eine AJAX-Anmeldeanforderung erneut ausgegeben wird. Die einzige Möglichkeit, dies zu verpfuschen, besteht darin, vor Abschluss der Anforderung auf OK zu klicken (oder versehentlich die Eingabetaste / Leertaste zu drücken, da OK - leider für diesen Fall - die Standardeinstellung ist). Es gibt andere Möglichkeiten, diesen Fall zu behandeln, z Erkennen von Drücken von F5 und Strg + R / Alt + R, was in den meisten Fällen funktioniert, jedoch durch Neukonfiguration der Tastenkombination oder alternative Verwendung des Betriebssystems vereitelt werden kann. Dies ist jedoch in der Realität ein Randfall. und die Worst-Case-Szenarien sind nie so schlimm: In einer Honor-System-Konfiguration würden Sie als falsche Person angemeldet sein (aber Sie können deutlich machen, dass dies der Fall ist, indem Sie Seiten mit Farben, Stilen, prominent angezeigten Namen personalisieren, etc.); In einer Kennwortkonfiguration liegt die Verantwortung bei der letzten Person, die ihr Kennwort eingegeben hat, um sich abgemeldet oder ihre Sitzung freigegeben zu haben. Wenn diese Person tatsächlich der aktuelle Benutzer ist, liegt kein Verstoß vor.
Am Ende haben Sie jedoch eine Anwendung für einen Benutzer pro Registerkarte, die (hoffentlich) genau so funktioniert, wie sie sollte, ohne dass Sie unbedingt Profile einrichten, den IE verwenden oder URLs neu schreiben müssen. Stellen Sie jedoch sicher, dass Sie auf jeder Registerkarte deutlich machen, wer auf dieser Registerkarte angemeldet ist.
quelle
Wir hatten dieses Problem und haben es sehr einfach gelöst. Ich meine einfach, weil keine Programmierung erforderlich ist. Wir wollten, dass sich ein Benutzer bei mehreren Konten innerhalb desselben Browserfensters anmeldet, ohne dass die Sitzungen in Konflikt geraten.
Die Lösung waren also zufällige Subdomänen.
Deshalb haben wir unseren Systemadministrator gebeten, die SSL-Zertifikate für * .abc.com anstatt abc.com zu konfigurieren. Mit wenig Codeänderung wird ein Benutzer jedes Mal, wenn er versucht, sich anzumelden, auf einer Registerkarte mit einer zufälligen Subdomain-Nummer angemeldet. So kann jede Registerkarte unabhängig eine eigene Sitzung haben. Um Konflikte zu vermeiden, haben wir die Zufallszahl mit einem Hash oder md5 der Benutzer-ID entwickelt.
quelle
Ich werde hier ehrlich sein. . . Alles oben Genannte mag wahr sein oder auch nicht, aber es scheint alles viel zu kompliziert zu sein oder es geht nicht darum zu wissen, welche Registerkarte serverseitig verwendet wird.
Manchmal müssen wir Occams Rasiermesser anwenden.
Hier ist der Ansatz des Occam: (Nein, ich bin kein Occam, er starb 1347)
1) Weisen Sie Ihrer Seite beim Laden eine eindeutige Browser-ID zu. . . genau dann, wenn das Fenster noch keine ID hat (verwenden Sie also ein Präfix und eine Erkennung)
2) Setzen Sie auf jeder Seite, die Sie haben (verwenden Sie eine globale Datei oder etwas anderes), einfach Code ein, um das Fokusereignis und / oder das Mouseover-Ereignis zu erkennen. (Ich werde jquery für diesen Teil verwenden, um das Schreiben von Code zu vereinfachen.)
3) Setzen Sie in Ihrer Fokus- (und / oder Mouseover-) Funktion ein Cookie mit dem Namen window.name
4) Lesen Sie diesen Cookie-Wert von Ihrer Serverseite, wenn Sie tabulatorspezifische Daten lesen / schreiben müssen.
Client-Seite:
Serverseite (C # - zum Beispiel Zwecke)
Getan.
quelle
Sie können das Umschreiben von Links verwenden, um eine eindeutige Kennung an alle Ihre URLs anzuhängen, wenn Sie mit einer einzelnen Seite beginnen (z. B. index.html / jsp / Whatever). Der Browser verwendet für alle Ihre Registerkarten dieselben Cookies, sodass alles, was Sie in Cookies einfügen, nicht eindeutig ist.
quelle
Ich denke, Sie möchten wahrscheinlich den Navigationsstatus über Registerkarten hinweg beibehalten und nicht speziell eine einzelne Sitzung pro Registerkarte erstellen. Dies ist genau das, was das Seam-Framework mit seinem Konversationsumfang / -kontext erreicht. Ihre Implementierung basiert auf der Tatsache, dass eine Konversations-ID mit jeder Anforderung weitergegeben wird und den Begriff einer Konversation auf der Serverseite erzeugt, die zwischen einer Sitzung und einer Anforderung liegt. Es ermöglicht die Steuerung des Navigationsflusses und die Statusverwaltung.
Obwohl dies hauptsächlich für JSF gedacht ist, schauen Sie nach, ob Sie hier einige Ideen finden können: http://docs.jboss.org/seam/latest/reference/en-US/html_single/#d0e3620
quelle
Wie kann ich in Javascript ein Browserfenster von einem anderen eindeutig identifizieren, das sich unter derselben Cookie-basierten Sitzungs-ID befindet?
Verwenden Sie im Wesentlichen window.name. Wenn es nicht festgelegt ist, setzen Sie es auf einen eindeutigen Wert und verwenden Sie es. Die Registerkarten, die zu derselben Sitzung gehören, sind unterschiedlich.
quelle
Ein anderer Ansatz besteht darin, eine eindeutige Fenster-ID zu erstellen und diesen Wert zusammen mit der Sitzungs-ID in einer Datenbanktabelle zu speichern. Die Fenster-ID, die ich oft benutze, ist (jetzt) eine Ganzzahl. Dieser Wert wird erstellt, wenn ein Fenster geöffnet und demselben Fenster neu zugewiesen wird, wenn das Fenster aktualisiert, neu geladen oder an sich selbst gesendet wird. Fensterwerte (Eingaben) werden über den Link in der lokalen Tabelle gespeichert. Wenn ein Wert erforderlich ist, wird er aus der Datenbanktabelle basierend auf der Verknüpfung Fenster-ID / Sitzungs-ID abgerufen. Während dieser Ansatz eine lokale Datenbank erfordert, ist er praktisch kinderleicht. Die Verwendung einer Datenbanktabelle war für mich einfach, aber ich sehe keinen Grund, warum lokale Arrays nicht so gut funktionieren würden.
quelle
Ich habe kürzlich mithilfe von Cookies eine Lösung für dieses Problem entwickelt. Hier ist ein Link zu meiner Lösung. Ich habe auch Beispielcode für die Lösung mit ASP.NET eingefügt. Sie sollten diesen bei Bedarf an JSP oder Servelets anpassen können.
https://sites.google.com/site/sarittechworld/track-client-windows
quelle
Spring Session unterstützt mehrere Sitzungen in demselben Browser. Sehen Sie sich die Beispiele und Implementierungsdetails an: http://docs.spring.io/spring-session/docs/current/reference/html5/guides/users.html
quelle
Hinweis: Die Lösung hier muss in der Phase des Anwendungsdesigns erfolgen. Es wäre schwierig, dies später zu konstruieren.
Verwenden Sie ein verstecktes Feld, um die Sitzungskennung weiterzugeben .
Damit dies funktioniert, muss jede Seite ein Formular enthalten:
Bei jeder Aktion auf Ihrer Seite, einschließlich der Navigation, wird das Formular zurückgeschickt (je
action
nach Bedarf). Für "unsichere" Anforderungen können Sie einen anderen Parameter einschließen, der beispielsweise einen JSON-Wert der zu übermittelnden Daten enthält:Da keine Cookies vorhanden sind, ist jede Registerkarte unabhängig und kennt keine anderen Sitzungen im selben Browser.
Viele Vorteile, insbesondere in Bezug auf Sicherheit:
Einige Nachteile:
Weitere Informationen hier .
quelle
Ich habe dies folgendermaßen gelöst:
hier der Code:
Ich hoffe dir zu helfen
quelle
Ich habe diesen Beitrag gelesen, weil ich dachte, ich wollte das Gleiche tun. Ich habe eine ähnliche Situation für eine Anwendung, an der ich arbeite. Und es geht wirklich darum, mehr als nur die Praktikabilität zu testen.
Nachdem ich diese Antworten gelesen hatte, insbesondere die von Michael Borgwardt, erkannte ich den Arbeitsablauf, der existieren muss:
Dies löst das Problem, dass Benutzer "Daten eines anderen Benutzers" in ihrer Sitzung sehen. Sie sehen nicht wirklich die Daten eines anderen Benutzers in ihrer Sitzung, sondern die Daten der einzigen Sitzung, die sie geöffnet haben. Dies führt eindeutig zu einigen interessanten Daten, da einige Vorgänge einige Sitzungsdaten überschreiben und andere nicht, sodass Sie eine Kombination von Daten in dieser einzelnen Sitzung haben.
Nun, um das Testproblem zu beheben. Der einzig praktikable Ansatz wäre die Nutzung von Präprozessor-Richtlinien , um zu bestimmen, ob Sitzungen ohne Cookies verwendet werden sollten. Indem ich eine bestimmte Konfiguration für eine bestimmte Umgebung einbaue, kann ich einige Annahmen über die Umgebung und deren Verwendung treffen. Auf diese Weise könnte ich technisch gesehen zwei Benutzer gleichzeitig anmelden, und der Tester könnte mehrere Szenarien aus derselben Browsersitzung testen, ohne sich jemals von einer dieser Serversitzungen abzumelden.
Dieser Ansatz weist jedoch einige schwerwiegende Einschränkungen auf. Nicht zuletzt ist die Tatsache, dass das, was der Tester testet, nicht das ist , was in der Produktion laufen wird.
Ich denke, ich muss sagen, das ist letztendlich eine schlechte Idee.
quelle
Speichern des Zeitstempels in window.sessionStorage, falls er noch nicht festgelegt ist. Dies gibt einen eindeutigen Wert für jede Registerkarte (auch wenn die URLs identisch sind).
http://www.javascriptkit.com/javatutors/domstorage.shtml
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
Hoffe das hilft.
quelle
Der einfachste Weg, Sitzungen in Browser-Registerkarten zu unterscheiden, besteht darin, Ihrer bestimmten Domain das Setzen von Cookies zu untersagen. Auf diese Weise können Sie separate Sitzungen auf separaten Registerkarten durchführen. Angenommen, Sie verbieten Cookies von dieser Domain: www.xyz.com. Sie öffnen Tab 1, melden sich an und beginnen zu surfen. Dann öffnen Sie Tab 2 und können sich entweder als derselbe oder als ein anderer Benutzer anmelden. In beiden Fällen haben Sie eine von Tab 1 getrennte Sitzung. Und so weiter.
Dies ist natürlich möglich, wenn Sie die Kontrolle über die Client-Seite haben. Andernfalls sollten die von den Leuten hier vorgeschriebenen Lösungen gelten.
quelle
Sie müssen tun
1- Speichern Sie ein Cookie für die Kontenliste
2- Optional können Sie ein Cookie für das Standard-Cookie speichern
3- Speichern Sie für jedes Konto mit seinem Index wie acc1, acc2
4- Geben Sie in die URL etwas ein, das den Kontenindex darstellt, und wenn nicht, wählen Sie den Standardindex wie google mail domain.com/0/some-url >> 0 aus. Stellen Sie hier den Kontenindex dar. Möglicherweise müssen Sie auch wissen, wie es geht benutze urlwrite
5- Wenn Sie ein Cookie auswählen, wählen Sie es entsprechend Ihrem URL-Pfad aus, der den Kontoindex darstellt
Grüße
quelle
Ich sehe viele Implementierungen, die clientseitige Änderungen aufweisen, um Sitzungs-ID-Cookies zu manipulieren. Im Allgemeinen sollten Sitzungs-ID-Cookies jedoch nur HttpOnly sein, damit Java-Script nicht darauf zugreifen kann, da dies sonst zu Session Hijack über XSS führen kann
quelle
Wenn auf jeder Registerkarte ein anderer Flow in Ihrer Anwendung ausgeführt wird und das Mischen beider Flows Probleme verursacht, ist es besser, Ihre Sitzungsobjekte zu "regionalisieren", damit jeder Flow einen anderen Bereich der Sitzung verwendet
Diese Region kann so einfach implementiert werden, dass für jeden Flow unterschiedliche Präfixe vorhanden sind, oder das Sitzungsobjekt enthält mehrere Zuordnungen (eine für jeden Ablauf), und Sie verwenden diese Zuordnungen anstelle von Sitzungsattributen. Am besten erweitern Sie jedoch Ihre Sitzungsklasse und benutze es stattdessen.
quelle