Ir al contenido


Foto

[RESUELTO] Dos o más aplicaciones con un soló login


  • Por favor identifícate para responder
26 respuestas en este tema

#1 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 06 abril 2011 - 09:37

Se trata compañeros saber como podría tener una aplicación llamemos maestra que me pida el login y luego otras auxiliares, que puedan leer los datos del usuario de la aplicación maestra y no pida el login si esta en uso y lo pida si no, pensé en principio en hacerlo con un archivo ini, pero veo el peligro de que si por cualquier motivo, rompa el programa y los datos del ini queden activos, sería bastante peligrosos en términos de seguridad del programa.


como siempre muchas gracias por vuestra ayuda.
  • 0

#2 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 abril 2011 - 10:08

Hola
Creo que lo mas sencillo, ''si se usa bd'' es que al loguearse el usuario se coloque como activo en la bd ''un campo adicional''.
Si esta activo, ya, si no, a loguearse.
Saludos
  • 0

#3 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 06 abril 2011 - 10:20

Simple y Eficaz, como siempre muchas gracias Caral.


Edito, pensándolo mejor, seguimos con el problema de si hay una caída de sistema, se quedaría como activo. sigo pensando que sería muy buena solución salvo por este detalle, tal vez una tabla en memoria, pero como leo una tabla en memoria si esta creada desde otra aplicación, no se si habría manera???.



  • 0

#4 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 06 abril 2011 - 10:25

Lo siento pero con la respuesta de Caral, que me pareció muy buena puse resuelto y ahora no puedo quitarlo.
  • 0

#5 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 abril 2011 - 10:36

Mira  este artículo de Sarko.

Saludos
  • 0

#6 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 abril 2011 - 11:17

Hola
Amigo para eso esta el evento OnDestroy.
Si el programa se cierra abructamente se actualiza la bd.
Por otro lado con un timer se puede verificar que la conexión a la bd este activa.
Te pongo un ejemplo, asi es como lo uso yo en mi programa, mas o menos. *-)
Saludos

Archivos adjuntos


  • 0

#7 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 06 abril 2011 - 11:26

Hola:

Para algo como esto me inclino por crear una .DLL, en la cual haya una variable global que indique si el usuario está autentificado o no, así como otros valores que quieras que se compartan. Cualquier programa que haga uso de dicha .dll sabrá si el usuario se identificó desde una aplicación previa y no lanzará el login. La ventaja de la .dll es que se borra su información al cerrar el sistema, y puede ser programada para que se elimine de la memoria en cuanto se cierre el último programa que hace uso de ella, de esa forma no tendrías que llevar un contador de "programas clientes", directamente se borraría la información del login con el último programa que la usara.

La .dll sería muy sencilla y podría incluir ella misma el formulario de login, de manera que con única función del tipo AutentificaUsuario(Name: string) : Boolean, si dicho usuario no está autentificado que lance el login, en caso contrario que devuelva TRUE sin mostrar ningún login.

Supongo que no debe ser muy complicado de hacer.
  • 0

#8 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 abril 2011 - 11:32

Hola
El problema es que las cosas hay que compararlas con algo.
Si el sistema se cae, CREO que lo que le preocupa a Jose Luis es que se cae la bd, no la aplicación, osea que no hay comunicación con la BD.
El programa puede estar activo, sin embargo la BD no.
Ahi es donde creo que esta el asunto.
Saludos
  • 0

#9 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 06 abril 2011 - 12:42

Hola Caral, vaya por delante que esto no lo he probado, pero se me ocurre que lo de utilizar una .DLL, o incluso un package de Delphi, es la mejor forma de unificar varias conexiones desde una sola máquina a una base de datos.

Hola
El problema es que las cosas hay que compararlas con algo.

En efecto, en ambos casos comparamos con un valor almacenado, pero mientras en el caso de la .DLL comparamos con un valor que reside en la memoria RAM, con la ventaja de que si cae el sistema se resetea a FALSE, si lo grabamos en la BD ese valor permanece a TRUE; en caso de que haya un corte de luz, por ejemplo, ¿cómo sabe el programa la próxima vez que arranca que no está autentificado si la BD le dice que sí?

Desde el punto de vista de la aplicación, el evento OnDestroy que comentas puede que no siempre esté en disposición de grabar nada en la BD, puesto que se supone que ha sucedido cualquier error inesperado, a partir de ahí no se garantiza que el programa sea capaz de hacer nada consistente.

Otra cosa es si, dependiendo del sistema de BBDD empleado, en su mecanismo de control de sesiones ya informa de si un usuario está o no conectado y con esa información es suficiente para no tener que preocuparse de nada más.

Si el sistema se cae, CREO que lo que le preocupa a Jose Luis es que se cae la bd, no la aplicación, osea que no hay comunicación con la BD.
El programa puede estar activo, sin embargo la BD no.
Ahi es donde creo que esta el asunto.
Saludos

Puede haber varios escenarios de "cuelgue", el sistema puede caer de muchas formas y hay que estar preparado para todas. Como dices, puede ser que la BD caiga, en ese caso puede que la aplicación se quede activa pensando erroneamente que está autentificada, lo que comentabas en un mensaje anterior de utilizar un Timer puede servir para testear si se ha perdido la conexión, y ese mecanismo puede realizarse tanto desde la misma aplicación como desde la propia .DLL que sirve de nexo a todas las aplicaciones.

Esto nos llevaría a un sistema mixto, preveyendo que caigan o bien el programa o bien la BD, en en ese caso cuando algunas de las dos informaciones de FALSE, se debe volver a autentificar.

Saludos

  • 0

#10 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 06 abril 2011 - 02:06

Hola
Me parece correcta tu apreciación. (y)
El problema mio es el desconocimiento del uso de DLL, casi no las he usado y cuando lo he hecho ha sido para regresar algún valor de una  función sencilla.
No me imagino como se podría usar para ese control, ya esta fuera de mi poco alcance. :

Saludos
  • 0

#11 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 07 abril 2011 - 01:01

Gracias a todo, aver si puedo responder, sn dejarme a nadie
Caral, estoy al igual que tu verde totalmente sobre DLL,  :embarrassed: confiezo que nunca las he usado, buscare a ver si hay algún tuto de como hacerlo, en cuanto a la caida, no estanto por el fallo del programa a ola caida de la base de datos, salvo fallo general claro, el problema que exponia, es que si el programa cae por el motivo que fuese, un apagón, etc, la base de datos quedaría con el usuario activo.

Wilson, interesante articulo, es una de las opciones que estoy barajando.

Andres1569, creo que el planteaminto en DLL que comentas sería el más correcto para lo que quiero, pero como confieso más arriva, no tengo ni idea de su uso, buscare aver si me entero de su uso y puedo aplicarlo.

Una aclaración sobre el sistema que comentaba, los programas auxiliares, no deben pedir el logo, si el programa general esta activo, pero no al revez. Lo comento por si esto afectara al diseño?.
  • 0

#12 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 abril 2011 - 04:39

El asunto de la DLL tiene un problema, las variables globales en una dll lo son sólo para cada  aplicación que la carga, no se comparten.

Es posible leer la en el espacio de direcciones de otro proceso (1 y 2) con las APIs VirtualAllocEx y WriteProcessMemory. Sin embargo se debe ser cuidadoso y tener en cuenta que un AV puede "Saltar". No creo que sea la forma de elección.

Quizás aquí 1, 2, 3 o 4 encuentres ayuda. 



Saludos.
  • 0

#13 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 07 abril 2011 - 11:46

Hola,

El asunto de la DLL tiene un problema, las variables globales en una dll lo son sólo para cada  aplicación que la carga, no se comparten.

Eso no es un problema, es un GRAN problema,  *-) , me he colado con el tema de las DLL, no tenía presente que no sirven para almacenar variables salvo datos estáticos (recursos y parecidos). Menos mal que Desart no ha empezado a programarlo, si no me hubiera puesto verde  :) .

Quizás aquí 1, 2, 3 o 4 encuentres ayuda. 
Saludos.

He mirado esos enlaces y creo que lo del enlace 1, donde pones un ejemplo de uso de ficheros compartidos en memoria, puede ser lo más recomendable para este propósito. A ese respecto me he acordado de un ejemplo que puso Al González en su bitácora sobre una clase llamada SuperGlobal que encapsulaba en un objeto Delphi el uso de esa memoria compartida, supongo que es parecido al ejemplo en C++ de SharedMemory que pusiste.

Saludos

Saludos

  • 0

#14 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 07 abril 2011 - 12:13

Andres1569 Verde , es que acaso te crees la masa (Hulk)  :D :D :D :D :D , nada hombre ahora en serio, tendré que estudiar bien el tema de Escafandra, pero por lo que he visto por encima también debería estudiar el tema de las DLL.


Ahora que recuerdo, teníaaaaaa una amigo que estudio en la universidad una carrera relacionada con la informática, y recuerdo que me dijo su último año, estoy deseando terminar la carrera, para dejar de estudiar, Pobre iluso.
  • 0

#15 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 abril 2011 - 12:26

... por lo que he visto por encima también debería estudiar el tema de las DLL.



Si estudialo pero no para tratar de usar Variables globales entre aplicaciones, te aseguro que no funcionará ;) .


Saludos.
  • 0

#16 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 07 abril 2011 - 01:21

Hola,

Siguiendo una de las propuestas de Escafandra, usando el mecanismo que ofrece Windows para manejar archivos compartidos en memoria, me he apoyado en un código que colocó Al González en su bitácora hace un tiempo, se trata de una clase llamada SuperGlobal que permite manejar un objeto desde varias aplicaciones dentro de la misma máquina, como si fuera una variable global a todo el sistema. Dicha clase almacena sus variables internas en esa memoria compartida, y facilita que se pueda usar desde varias aplicaciones que instancien dicha clase. Ignoro si puede dar algún efecto secundario esa técnica, yo lo he probado en Windows 7 y de momento funciona correctamente.

Lo único que hago es derivar de TSuperGlobalObject una clase llamada TDBLogin, que mantiene una lista de usuarios autentificados, para su consulta por parte de varias aplicaciones escritas en Delphi. Esta clase dispone de tres métodos básicos, para añadir un usuario (método LogUser), otra para quitarlo (método UnlogUser), y otra para consultar si un usuario ya está autentificado previamente (método UserIndex que devuelve un número mayor a -1 si ya estaba en la lista).

Para almacenar los usuarios se utiliza una estructura de registro, que almacena una cadena (UserName : string[64]) para el nombre de usuario y un contador (ClientCount : Integer) para memorizar el número de aplicaciones que usan dicho usuario, de esta forma cuando una aplicación da de alta un usuario se incremente el contador y cuando lo da de baja se decrementa, y sólo se elimina el usuario de la lista cuando ya no hay ninguna aplicación que lo use. Este sistema es mejorable, desde luego, y debe usarse con algunas precauciones, es decir, cada aplicación debe llamar a UnLogUser tantas veces como haya llamado a LogUser. Y por descontado, se presupone que el proceso de logueo a la BD le corresponde a la aplicación, la clase TDBLogin sólo informa de los usuarios que le indiquemos.


Hay que tener en cuenta que, como señala Al González en la explicación de su código, se prohibe el uso de punteros, por lo que la clase TDBLogin no declara listas dinámicas, ni estructuras del tipo TList, por lo que uso un array acotado a 20 para almacenar los usuarios, y las cadenas tienen una longitud fija. Se puede ampliar la clase para almacenar más información teniendo en cuenta esa limitaciones.

Ficheros adjuntos:

AGSuperGlobals.pas => Código de Al González que implementa la clase TSuperGlobalObject

DBLogin.pas => Código que implementa una sencilla clase TDBLogin, descendiente de TSuperGlobalObject, y que se encarga de almacenar los usuarios que le indiquemos.

Resto de archivos => Un programa de ejemplo, PruebaDBLogin, que muestra el uso de esa técnica. Basta con ejecutar varias instancias de dicho programa y jugar con él para ver cómo se comparte la información entre varias aplicaciones.


Saludos

Archivos adjuntos


  • 0

#17 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 07 abril 2011 - 03:13

Hola
Muy interesante.
Entonces el uso de  .pas hace la funcion que podria hacer una dll o varias dll compartiendo recursos?.
Interesante tema.

Saludos
  • 0

#18 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 07 abril 2011 - 04:15

Personalmente no me gusta mucho la idea "SuperGlobal". Si se comparten las propiedades de una clase de forma global ¿donde queda, entonces, la encapsulación? todo el trabajo de la POO lo deshacemos.

Prefiero compartir justo lo necesario y nada mas, así nada se escapará de las manos.  :) 



Saludos.
  • 0

#19 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 07 abril 2011 - 08:25

Independientemente de los buenos aportes que han hecho los compañeros, me queda una duda en el planteamiento inicial del problema; supongamos que el usuario "Pedro perez" se logueó en la aplicación "A", paso seguido se carga la información de Pedro Perez  bien sea en: (La DB, el archivo Ini, La Clase SperGlobal, la DLL o en lo que quieran), luego Pedro Perez abre la aplicación "B", por lógica es la aplicación "B" la que debe averiguar si Pedro Perez ya está logueado, bien sea en: (La DB, el archivo Ini, La Clase SperGlobal, la DLL o en lo que quieran); ahora bien,  mi pregunta es: ¿Como sabe la aplicación "B" que es Pedro perez el que está  accediendo a la aplicación? Digamos que si está en una red la única opción sería la IP, pero no podría identificar al usuario,  si Pedro Perez está en la misma maquina como hace?.

Yo creo que debe necesariamente  identificarse.

La solución que yo propongo es una pequeña aplicación que haga las veces de recepcionista (que permanecerá siempre abierta), el usuario solo se loguea una única vez  en la recepción, y las aplicaciones dependientes no se ejecutan directamente si no que las ejecuta la aplicación  recepcionista. Dicha aplicación podría ser un form fsStayOnTop con tantos botones como aplicaciones necesite manejar, lo demás es carpintería.

Saludos
  • 0

#20 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 08 abril 2011 - 01:02

Wilson, te comento, tienes razón sólo en un 50% :| , el problema del otro 50% es de La Ley de protección de datos, que te obliga a que todos los programas que contengan datos, tengan como mínimo un login de acceso.

El programa que estoy haciendo en mi empresa, me parece que es demasiado grande, por eso lo divido en el programa general y varios auxiliares, claro cada uno tiene que logearse, por eso planteaba este problema.  Normalmente usare yo el program,a y hare las llamadas desde el programa Principal, pero otras veces puedes necesitar  usar sólo un auxiliar.

Mi siguiente duda lógica sería, que pidiese el logín si se abre desde otro punto de la red.????
  • 0




IP.Board spam blocked by CleanTalk.