2010-03-25 3 views
15

Ich habe ASP.net-Anwendung, die im Grunde ein Dateneingabebildschirm für einen physischen Prüfprozess ist. Die Benutzer möchten in der Lage sein, mehrere Browserfenster geöffnet zu haben und Daten von mehreren Prüfungen gleichzeitig einzugeben. Zuerst verwendete ich Cookie-basierte Sitzungen und offensichtlich explodierte dies.Wie zu verhindern, dass mehrere Browser-Fenster die gleiche Sitzung in asp.net teilen

Ich wechselte auf die Verwendung von Sitzungen ohne Cookies, die die Sitzung in der URL speichert und beim Testen schien dies das Problem zu lösen. Jedes Browserfenster/jeder Tab hatte eine andere Sitzungs-ID, und die in einem Browser eingegebenen Daten übertrafen nicht die Daten, die in dem anderen eingegeben wurden.

Allerdings sind meine Benutzer effizienter beim Brechen der Dinge, als ich erwartet hatte und es scheint, dass sie immer noch die gleiche Sitzung zwischen den Browsern manchmal bekommen. Ich denke, dass sie die Adresse von einem Tab zum anderen kopieren/einfügen, um die Anwendung zu öffnen, aber ich konnte dies noch nicht überprüfen (sie sind an einem anderen Ort, so dass ich sie nicht einfach fragen kann)).

Anders als zu sagen, dass sie nicht kopiert und eingefügt werden, oder sie davon überzeugen, nur eins nach dem anderen einzugeben, wie kann ich verhindern, dass diese Situation eintritt?

+1

Ich kann falsch liegen (daher nicht als Antwort), aber ich glaube, das ist eine Browser-Einschränkung. Anders als bei der Methode ohne Cookies, die Sie ausprobiert haben, ist es meiner Meinung nach nicht sehr einfach, Browser dazu zu bringen, unabhängige Sitzungen auf Tabs zu verwenden. Schlimmer noch, selbst wenn Sie einen Browser dafür verwalten, gibt es immer noch die anderen zu "reparieren". – keyboardP

Antwort

4

Stellen Sie sich ViewState anstelle von Session vor, da ViewState Statusinformationen für den Client (HTML-Seite) darstellt. Ich bin mir nicht sicher, ob Sie jemals in der Lage sein werden, detaillierte Kontrolle über das Sitzungsverhalten des Browsers zu erlangen, da die Sitzungs-ID vom Browser so verwaltet wird, wie der Hersteller es getan hat. ViewState ist also nicht nur vorhersehbar, sondern auch für zukünftige Browserversionen.

+1

Nur um klar zu stellen, mit "sicher", ich vermute, Sie meinen nicht aus einer Hackerangriffsperspektive. – keyboardP

+0

Nein, gar nicht, du hast Recht. Ich habe den Beitrag bearbeitet. –

2

Müssen die Benutzer mit unterschiedlichen Konten angemeldet sein, um auf verschiedene physische Prüfungen zugreifen zu können? Es scheint mir, dass, solange die PhysicalInspectionID Teil der URL ist, sollte es kein Problem sein, mehrere physische Prüfungen gleichzeitig zu bearbeiten.

Z. B.

http://inspections.mydomain.com/edit/23

Natürlich, wenn sie die URL kopieren, werden sie ein Duplikat des anderen Fenster bekommen, aber das wird sie nicht lehren, das zu tun. Stattdessen öffnen sie ein weiteres Fenster und navigieren über die Benutzeroberfläche zur richtigen Überprüfung (oder fügen eine neue hinzu).

0

Erstellen Sie eine neue sessionId, wenn die Anfrage keinen Referer hat. Das löst das Copy-Paste-URL-Problem. Speichern Sie die Session-ID in der URL wie bei Ihnen.

3

das ist eine sehr gute Frage, über die ich auch lange nachgedacht habe.

Speichern Sie Ihre Hauptwebseite in einem iframe. Haben Sie JavaScript, um zu überprüfen, ob sich Ihre Webseite noch im übergeordneten iframe befindet. Wenn nicht, haben sie mehrere Browserfenster geöffnet.

Sie müssen sicherstellen, dass Ihre gesamte App iframe freundlich ist.

+3

hast du es tatsächlich gesagt. Zuerst dachte ich, du machst Witze, aber ich glaube nicht, dass du es bist. IFRAME? – jDeveloper

3

Ich bin mir nicht sicher, warum Sie eine Sitzung auf nur einen Prüfvorgang beschränken möchten, und erzwingen dann mehrere Sitzungen, damit Benutzer gleichzeitig an mehreren Prüfungen arbeiten können. Das fühlt sich an wie eine ziemlich peinliche Art von Isolation.

Die Webanwendung (und die Seiten) sollten in der Lage sein, mehrere Prüfprozesse innerhalb einer einzelnen Benutzersitzung zu bearbeiten.

Alle Daten, die in Sitzungsvariablen gespeichert sind, sollten nicht eindeutig für die singuläre Behandlung verfügbar gemacht werden.Sie sollten in Sammlungen gespeichert werden, die leicht identifizieren, welcher Datensatz zu welchem ​​Prüfprozess gehört. Jede Seitenübergabe zurück an den Webserver sollte eine Kennung tragen, zu welchem ​​Inspektionsprozess es gehört, damit der richtige Sitzungssatz angepasst und zur Verwendung gezogen werden kann.

<script language="javascript" type="text/javascript"> 
    @if(Request.IsAuthenticated) 
    { 
     <text> 
     if (window.name != 'singleWindow') { 
      window.location.href = "Content/ErrorPages/SingleTab.htm"; 
     } 
     </text> 
    } 
    else 
    { 
     <text> 
     window.name = "singleWindow"; 
     </text> 
    } 
</script> 

Im Grunde ist dies setzt den Fensternamen erstes Mal, wenn: mehrere Registerkarten zu öffnen

Pseudo-Code Konzept

var inspectionID = this.inspectionLabel.Text; 
var inspectionSets = (Hashtable)Session["inspections"]; 
var inspection = (Inspection)inspectionSets[inspectionID]; 
1

Dies ist, was ich in ASP.NET MVC verwenden authentifizierte Benutzer zu verbieten Der Benutzer besucht die Anmeldeseite. Nach dem Einloggen wird für jeden nachfolgenden Seitenladevorgang der Fenstername getestet.

Zwei Probleme:

  • Wok nicht, wenn JavaScript deaktiviert
  • wenn versehentlich die Benutzer die ursprünglichen Registerkarte werden geschlossen, und fügen dann einen anderen Link zu meiner Website in der Adressleiste, wird der Benutzer immer erhalten die Fehlerseite. Um dem Benutzer eine Chance zur Wiederherstellung zu geben, habe ich den "Abmelden" -Link auf der SingleTab.htm-Seite eingefügt, so dass der Benutzer seinen Session-Cookie löschen und eine neue Sitzung starten kann.
2

Eine Lösung für dieses Problem kann durch die folgende implementiert werden:

public static class CommonHelper 
{ 
    public static bool SiteGuard 
    { 
     get 
     { 
      if(HttpContext.Current.Session["SiteGuard"] == null) 
       return true; 
      return (bool)HttpContext.Current.Session["SiteGuard"]; 
     } 
     set 
     { 
      HttpContext.Current.Session["SiteGuard"] = value; 
     } 
    } 
} 

public partial class TestPage : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if(!Page.IsPostBack) 
     { 
      bool go = false; 
      for(int i = 0; i < 50; i++) // wait for the service to work (5 secs max) 
      { 
       if(CommonHelper.SiteGuard) 
       { 
        go = true; 
        break; 
       } 
       Thread.Sleep(100); 
      } 
      if(!go) 
       Response.Redirect("Login.aspx"); 

      SiteGuard = false; // from now on, nobody can visit your site 
     } 
     // Now as long as Page.IsPostBack is true you are in a good shape 
    } 
} 

eine asmx Web-Dienst (oder jede andere Art von Dienstleistungen, die Sie denken, ist geeignet), um Ihre Stammprojekt und fügen Sie den folgenden hinzufügen Methode zu:

[WebMethod(EnableSession = true)] 
    public void FreeSiteGuard() 
    { 
     HttpContext.Current.Session["SiteGuard"] = null; 
    } 

In der Master-Seite oder auf jeder Seite fügen sie den folgenden javascript:

<script type="text/javascript"> 
    window.onbeforeunload = function (e) { 
     e = e || window.event; 
     if (e) { 
      // Invoke web service 
      YourProject.YourWebServiceName.FreeSiteGuard(); 
     } 
    }; 
</script> 

Beachten Sie, dass die Reaktionszeit Ihrer Website durch die Geschwindigkeit des Webdienstes beeinflusst wird.

+0

Was passiert, wenn der Benutzer JavaScript aktiviert? – kat1330

+0

Sie können dies erkennen und verhindern, dass der Benutzer von Anfang an etwas tut. Fordern Sie ihn auf, JavaScript zu aktivieren. – yazanpro

+0

Sie können den Webservice-Aufruf durch einen Ajax-Aufruf für eine Seite innerhalb der Webanwendung ersetzen. – ZooZ

Verwandte Themen