2009-02-17 23 views
11

Me pregunto si es posible determinar si un usuario ya tiene un navegador web abierto para la aplicación web en la que estoy trabajando. Parece que pueden abrir varias instancias de la misma aplicación web y hacer clic en los botones para leer la información que han utilizado antes para ingresar a una pantalla de entrada en la que están trabajando actualmente.Cómo evitar que un usuario tenga varias instancias de la misma aplicación web

Lo que sucede es que parece arruinar las variables de la sesión y luego el usuario actualizará su trabajo anterior con su nuevo trabajo. O van a eliminar sus trabajos anteriores todos juntos o quien sabe ...

EDITAR he visto este hecho antes con las aplicaciones web de banca en línea. Si ya ha iniciado sesión, la nueva ventana le indicará amablemente que ya tiene la aplicación abierta. En mi caso, el usuario no necesita iniciar sesión.

Existe una manera simple de determinar si ya tienen una ventana del navegador abierta para la aplicación web y, de ser así, simplemente cierre el navegador o visualice una página diferente para hacerles saber que solo pueden tener 1 abierto a la vez?

Gracias

+0

De nuevo, ya que al parecer tiene dificultades para leer los registros de cambios de revisión: Vea SOFAQ - por favor no cree nuevas etiquetas si ya hay buenas. La etiqueta VS2005 es visualstudio2005. –

+2

Estarías mucho mejor arreglando su sitio para que los usuarios lo puedan abrir en dos pestañas. Este es el comportamiento esperado, y su sitio debería soportarlo. – meagar

+0

Me gustaría saber esto también. Presionar Ctrl-N en Internet Explorer 6 no parece desencadenar nada dentro del DOM o en la red que le permita tomar medidas para la duplicación de la ventana. He intentado un par de cosas como usar el evento Onload en el cuerpo, nada. – Tommy

Respuesta

0

Puede comprobar si el usuario tiene más de una sesión activa. Esto podría funcionar, pero podría ser problemático ya que no hay una buena forma de determinar si una sesión está realmente activa o no.

2

Utilizo el truco de abrir una nueva ventana con una identificación específica y siempre me aseguro de que cualquier página que se abra siempre use esa ventana.

El inconveniente es que deben tener su bloqueador de ventanas emergentes desactivado para su sitio. Funciona bien para los sitios de la compañía.

if (useOwnWindow && window.name != 'YourAPP'){ 
    var w = window.open(document.location, 'YourAPP', 'toolbar=no,status=yes,resizable=yes,scrollbars=yes'); 
    if (w==null){ 
     alert("Please turn off your pop-up blocker"); 
    }else{ 
     window.open('','_parent',''); 
     self.opener=""; 
     self.close(); 
    } 
} 

nota la bandera useOwnWindow si es utilizado por los desarrolladores para que podemos abrirlo varias veces

+0

¡Para mí, esto funcionó a la perfección! Gracias. – ZooZ

3

¿Hay una manera sencilla para determinar si ya tienen una ventana del navegador abierta a la aplicación web y Si es así, solo cierre el navegador o muestre una página diferente para hacerles saber que solo pueden tener 1 abierto a la vez.

En resumen, Nº
Sin escribir algún tipo de control ActiveX, no hay código que podría escribir que podría detener el usuario abra un (instancia separada de) IE/FF, etc y tener una instancia detectar el otro.

3

Puede asignar una ID de 'mini-sesión' a cada instancia del formulario de entrada, luego use AJAX para hacer ping al servidor con esa ID. Si el usuario intenta solicitar el mismo formulario cuando hay una identificación activa, debe mostrar un mensaje de error. Si el servidor no escucha el ping durante un cierto período de tiempo, caduque la mini-sesión. (Esta es básicamente una estrategia de bloqueo muy simple)

1

Sugeriría que hash el ViewState para la página y lo almacene en una variable de sesión antes de que se devuelva como respuesta.

Luego de una primera solicitud de comprobar el hash de la ViewState vuelto contra la que tiene en la variable de sesión y si no coinciden no procesar cualquier cambio en la página y mostrar un aviso al usuario o redirigen a una página de error.

Los dos métodos de la clase Page que desea sobrescribir son;

protected override object LoadPageStateFromPersistenceMedium() 

protected override void SavePageStateToPersistenceMedium(object viewState) 
+0

Uhm ... ¿no serían dos inicios de sesión separados el resultado en dos cachés de sesión separados. La memoria caché de sesión de ASP.Net no tiene ningún concepto de usuarios. – PeterR

8

En primer lugar, no, no, y en segundo lugar, no deberías intentarlo.

La estrategia de la ventana emergente no funcionará (y molestará a los usuarios). Tengo mi navegador configurado en 'Abrir ventanas como pestañas', y I elegir si dividir uno en otra ventana. O en algunos casos, si ejecuta un navegador diferente, no solo otra instancia del mismo, para mostrar otra página en el mismo sitio.

Por el contrario, la identificación de mini-sesión fallará porque el servidor no puede realizar un seguimiento de si una solicitud es del mismo usuario como una sesión existente. Varias personas pueden estar usando la misma máquina, incluso con el mismo nombre de usuario; o una persona puede tener varias sesiones de inicio de sesión separadas, en una o varias máquinas.

Simplemente solucione sus variables de protocolo vs. 'Sesión' y asegúrese de que los últimos cambios confirmados sean los que persisten.

1

Hemos implementado una solución a este problema en slicethepie.com. Los usuarios (o "exploradores") solo pueden tener una ventana del navegador abierta a la vez para asegurarse de que escuchan la música que se les paga para revisar.

Cuando un explorador solicita la primera pista para revisar en su sesión de exploración, establecemos un nuevo Guid en su cuenta y devolvemos esta "clave" junto con los detalles de la pista que se les está dando para revisar. Sucede que el destinatario de esta clave es una película flash, pero no tiene que ser así. La clave se vuelve a enviar junto con la revisión del explorador, y verificamos si coincide con la clave guardada. Si no es así, han comenzado una nueva sesión de exploración en una nueva ventana.

No estoy implicando que este método sea infalible, pero podría adaptarse a sus necesidades con bastante facilidad.

+0

mis usuarios no tienen cuentas, pero este concepto es interesante. Supongo que mi mayor problema al implementar esto sería poder rastrear si el usuario ha salido y vuelto a abrir una nueva ventana o si nunca han salido y abierto otra ventana. – Eppz

1

Como han mencionado otros, no se puede evitar que el usuario inicie una nueva sesión sin recurrir a ActiveX u otra maldad. El problema básico es que no hay forma de que usted sepa si un usuario cerró la ventana del navegador anterior o la dejó abierta.

Lo que puede hacer, sin embargo, es invalidar la sesión anterior tan pronto como el usuario inicie sesión en una nueva (un poco similar al comportamiento de los clientes de mensajería instantánea).

En cada inicio de sesión, asigne un nuevo GUID al usuario en su base de datos. También almacene este GUID en el caché de la sesión (No es necesario enviarlo de ida y vuelta a las páginas, lo que no funcionará para las solicitudes GET de todos modos). En cada solicitud de página, compare el GUID asignado al usuario en la base de datos con el GUID en la memoria caché de la sesión. Si no coinciden, devuelve una respuesta "Has iniciado sesión desde otro lugar".

Actualización Estaba un poco demasiado rápido en el gatillo. Esto no evita el escenario donde el usuario abre múltiples pestañas/ventanas dentro del mismo proceso del navegador. Así que tendría que combinar esta solución con la sugerencia de Dave Anderson para almacenar un hash ViewState (o simplemente un GUID) para que solo la última página servida en una sesión pueda publicar de nuevo.

Actualización de seguridad Además, solo puede confiar en este marco como una conveniencia para el usuario, ya que no es seguro. Cualquier hacker medio decente será capaz de eludir estas medidas.

0

Si alguien copiar la URL del sitio web y pegarlo en una nueva ventana o pestaña, el historial del navegador para esa ventana/pestaña estará vacía ... y lo puede utilizar javascript y comprobar el historial ..

if (history.length == 1) { //0 for IE, 1 for Firefox 
    // This is a new window or a new tab. 
} 

Ahora puede pedirle al usuario que cierre la pestaña, o deshabilitar esa página (haciendo todos los elementos disabled por ejemplo).

3

Todo lo que tiene que hacer es asignar un valor tanto al valor del control de Entrada Oculta como a una variable de sesión en el evento Carga de Página y en la devolución, comprobar el valor de la variable local contra el valor en la variable de sesión. Si los valores no coinciden, puede redirigir al usuario a la página de inicio de sesión o una página que les dice que la sesión de esa página ya no es válida, etc.

Ejemplo:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Try 
     If Not IsPostBack Then 
      'SET LOCAL VARIABLE AND SESSION VARIABLE TO A UNIQUE VALUE 
      'IF THE USER HAS CHANGED TABS THIS WILL CHANGE THE VALUE OF THE SESSION VARIABLE 
      Me.HiddenInput.value = New Guid().ToString 
      Me.Session.Add("PageGuid", Me.HiddenInput.value) 

     Else 
      'ON POSTBACK, CHECK TO SEE IF THE USER HAS OPENED A NEW TAB 
      'BY COMPARING THE VALUE OF THE LOCAL VALUE TO THE VALUE OF THE SESSION VARIABLE 

      If me.HiddenInput.value <> CType(Session("PageGuid"), String) Then 

       'THE VALUES DO NOT MATCH, MEANING THE USER OPENED A NEW TAB. 
       'REDIRECT THE USER SOMEWHERE HARMLESS 

       Response.Redirect("~/Home.aspx") 

      Else 

       'THE VALUES MATCH, MEANING THE USER HAS NOT OPENED A NEW TAB 
       'PERFORM NORMAL POSTBACK ACTIONS 

       ... 

      End If 
     End If 
    Catch ex As Exception 
     Me.Session.Add("ErrorMessage", BusinessLogic.GetErrorMessage(ex)) 
     Me.Response.Redirect("~/ErrorPage.aspx", False) 
    End Try 
End Sub 
+0

Esta solución no me funciona, intento abrir 2 pestañas para la misma página. –

1

Puede detener la funcionalidad de la página cuando el usuario abre otra pestaña o una ventana o incluso otro navegador

$(window).blur(function(){ 

// code to stop functioning or close the page 

}); 
0

yo tenía el mismo problema y lo resolvió mediante sockets web (yo uso empujador con php). Cuando el usuario accede a la página que establece una variable:

var firstTimeHere = true; 

Entonces hice una función WebSocket en javascript que tiene el ID de usuario como parte del nombre de la función como:

var pingUser123 = function(){...}; 

Luego uso ajax para consultar el servidor en el que se activa el lado de la php WebSocket:

$this->trigger("pingUser123"); 

el WebSocket desencadena todos los casos de esa función javascript en cualquier número de ventanas a través de cualquier número de navegador s y máquinas. A partir de ahí, puedo ver si es la primera vez que se hace ping a este navegador. si es así, es la única instancia, si no hay una segunda.

var pingUser123 = function(){ 
    if(firstTimeHere){ 
     firstTimeHere = false; 
    }else{ 
     app.stop(); 
     alert("Only one window at a time please."); 
    } 
}; 
0
<script type="text/javascript"> 
     window.onload = function(){ 
     if (document.cookie.indexOf("_instance=true") === -1) { 
     document.cookie = "_instance=true"; 
     // Set the onunload function 
     window.onunload = function(){ 
      document.cookie ="_instance=true;expires=Thu, 01-Jan-1970 00:00:01 GMT"; 
     }; 
     // Load the application 
     } 
     else { 
      alert(" Security Alerts.You Are Opening Multiple Window. This window will now close."); 
      var win = window.open("about:blank", "_self"); win.close(); 
     // Notify the user 
     } 
     }; 
    </script> 
1

I parcialmente resuelto el problema de esta manera. Mi aplicación solicita autenticación a los usuarios ... por lo que teclean un nombre de usuario y una contraseña. Cuando hacen clic en el botón de enviar, guardo ambos datos en la variable de sesión, es decir, guardo el nombre de usuario en Session ("LoginName").

Este es el truco: simplemente pruebe si Session ("LoginName") tiene un valor ANTES de que el usuario lo ingrese, en el evento de carga de la página de inicio de sesión. Si es así, esta es una sesión múltiple y puede detener al usuario o lo que sea.

Algo así (yo uso VB):

If Not Page.IsPostBack Then 
     Try 
      If Session("LoginName") <> "" Then 
      Response.Redirect("www.mysite.com") 
      Exit Sub 
      End If 
     Catch ex As Exception 
      ' Do something 
     End Try 

PRO: muy simple

CON: el usuario puede copiar la dirección de una página interior y pegarlo en otra pestaña del mismo navegador .. . Es por esto que dije "parcialmente"

0

Puede hacerlo por window.name. En java script window.name tiene un valor en blanco en cada nueva pestaña. Establezca el valor window.name en la página de inicio de sesión y guárdelo en la sesión.

window.name = Math.random() + "_YourApplication" 

Ahora compruebe este window.name en la página maestra/página de diseño. Cierre la sesión de usuario si contiene varias pestañas.

if (!window.name || window.name != '@Session["WindowName"]') { 
    //Log Off code 
} 
Cuestiones relacionadas