2012-02-09 46 views
5

Estoy desarrollando un sitio ASP.net (usando .NET 4, EF, jQuery Ajax, SQL Server 2008 R2). En este sitio quiero evitar multi-login. Me refiero a que si inicia sesión en el sitio, no puede volver a iniciar sesión en el sitio desde otro navegador o computadora ya que ya inició sesión.¿Cómo evitar que los usuarios inicien sesión en mi sitio más de una sesión?

que plantar una idea y desarrollado en mi sitio, pero tiene un problema y es debido a ese problema que decido hacer una pregunta aquí

Tengo una tabla de SQL Server como esto:

Id  [int]   NOT NULL IDENTITY(1,1) //PK 
UserId [int]   NOT NULL     //Relation to User table 
Key  [nvarchar](50) NOT NULL     //Unique 

Cuando un usuario inicia sesión en el sitio, que insertar una fila en esta tabla como esta:

UserId = The Id of logged in user 
Key = Session.SessionId 

y también hay un código para eliminar un registro de esta tabla que ejecutar WH en:

  1. usuario intenta cerrar la sesión de su cuenta de
  2. en Session_End evento en global.asax

Todo funciona correcta y perfecta, simplemente:

Problema: cuando el usuario cierra el navegador , esa fila no se borra (pensé que cuando cierra el navegador, su fila en esa tabla se eliminará en el evento Session_End, pero no lo hizo !!!)

¿Qué puedo hacer? ¿Alguna solución para este problema? ¿Debo cambiar mi estrategia o hay una solución?

Disculpa por mi mala sintaxis. Soy nuevo en Inglés

Cualquier idea puede ser útil

respecto

Foroughi

Update1: No consumo ASP membresía y administrar mis usuarios a mí mismo

ACTUALIZACIÓN2: uso InProc mo de mi estado de sesión con 20 minutos de tiempo de espera

+6

¿No es más fácil desconectarse de la sesión existente cuando el usuario inicia un nuevo inicio de sesión? Esto también es más práctico cuando el usuario olvida cerrar la sesión en una ubicación diferente (por ejemplo, casa/trabajo). –

+0

@marc_s gracias amigo y perdón por ellos –

+0

@AliForoughi: no hay problema - la pregunta sigue siendo clara y perfectamente comprensible –

Respuesta

2

El evento Session_End no se activa cuando el navegador está cerrado, se dispara cuando el servidor no ha recibido una solicitud del usuario en un período de tiempo específico (por defecto 20 minutos) Esto significa que si usa Session_End para eliminar usuarios, no podrán iniciar sesión durante 20 minutos después de que hayan cerrado el navegador.

Dos estrategias alternativas vienen a la mente

  1. Usted puede utilizar el evento onunload en el navegador para enviar una solicitud de cierre de sesión al servidor cuando el usuario abandona la página (Por supuesto, esto sólo funciona si el usuario sigue tiene conectividad de red). El evento onunload también se activa cuando recargas la página, por lo que tendrías que hacer un seguimiento de por qué se desencadena el evento para usarlo.

  2. Guarde la hora de la última solicitud en el objeto de usuario. De esta forma puede determinar cuán activo es el usuario y qué probabilidades hay de que hayan abandonado el sitio. Por ejemplo, encuentre a cualquier usuario que no haya hecho nada durante dos minutos y desconéctelo.

EDIT: Como punto final se crió en los comentarios. En lugar de ver su requerimiento como ', solo puede tener un nombre de usuario, por lo que si ya inició sesión no permite iniciar sesión' puede cambiar a 'solo puede tener un nombre de usuario si tiene una sesión abierta, se cancelará y uno nuevo creado. '

De esta manera usted todavía conserva su sesión de inicio de sesión por regla de cuenta, mientras que proporciona un método mucho más robusto para aplicarla.

+0

Actualizo mi pregunta, ¿qué piensas ahora? –

+0

Creo que el primero no es lo suficientemente bueno, pero el segundo es bueno y voy a trabajar en ello, gracias hombre :) –

+1

Los métodos se pueden combinar para obtener lo mejor de ambos mundos. –

1

El problema que tiene, además de cómo/dónde almacena el estado, es que un usuario no puede desconectarse y dejar una sesión activa. Sugiero lo siguiente:

1) Cambio de estado (Eliminar registro en su caso) cuando el usuario cierra la sesión o cuando finaliza la sesión (la sesión termina después de n minutos de inactividad, consulte a su web.config y Global.asax para el controlador de eventos)

2) Si un usuario intenta iniciar sesión por segunda vez, ofrece la opción de cerrar la sesión anterior.

+0

Actualizo mi pregunta, ¿qué piensas ahora? –

0

Creo que deberías probar smth. de esta manera:

estructura de la tabla:

ID 
UserID 
Flag 

Cuando el usuario se registra en que actualice su tabla y conjunto del indicador de cierto o y cuando se registra a cabo la puso a falsa o

Cuando el usuario cerró su navegador, debe decidir si lo desconecta o no. Si es así - se captura este evento como Session_End y hace que ingrese a cabo por sí mismo y actualizar la tabla de falsa o

2

En primer lugar no utilice la base de datos como un sistema de mensajería. Esa es una receta para el desastre.

Lo que debe hacer es tener un diccionario que contenga los identificadores de usuario registrados y su última acción en el almacenamiento de la aplicación. También agregue script en todas las páginas que haga ping al servidor cada 2 a 5 minutos.

Una vez que se recibe un ping, actualice la última hora de actividad del id del usuario y elimine cualquier id de usuario que haya "agotado el tiempo de espera".

+0

desastre? WOW, tu idea parece buena, voy a trabajar en eso amigo, gracias :) –

+1

La razón por la cual es una mala idea usar la base de datos para mensajes en general es que es muy ineficiente. En este caso, podría usar el almacenamiento de la aplicación, que es mucho más rápido. También en otras situaciones necesita implementar sistemas complejos en la parte superior de la base de datos para que la comunicación funcione correctamente (por ejemplo, revisiones periódicas en lugar de confiar en eventos, limpiezas periódicas, verificaciones para ver si el mensaje fue leído, hacer cola, etc.). Todos estos mecanismos generalmente se implementan en marcos de comunicación entre procesos adecuados. – linkerro

+0

"verificaciones periódicas en lugar de confiar en los eventos"? !! Sí, te tengo, no es mala idea, gracias linkerro. Creo que quieres almacenar información de sesión en un estado de aplicación en lugar de DB, y almacenar su última actividad? –

Cuestiones relacionadas