• Publicidad

Control de acceso CGI::Session

Aquí encontrarás todo lo que sea específicamente acerca de módulos de Perl. Ya sea que estás compartiendo tu módulo, un manual o simplemente tienes una duda acerca de alguno.

Re: Control de acceso CGI::Session

Notapor noa86 » 2011-03-29 17:49 @784

He reiniciado el ordenador y me ha dejado de dar ese error.

Pero poniéndolo como hemos comentado ahora sigue sin funcionarme is_expired(), y además me ha dejado de funcionar bien las sesiones, ya que cada vez que ejecuto el cgi tengo que iniciar sesión, como si no me la guardara, y cuando tenía puesto el new() una vez iniciada sesión no tenía que volver a iniciar a no ser que cerrara el navegador o expirara el tiempo...
noa86
Perlero nuevo
Perlero nuevo
 
Mensajes: 93
Registrado: 2010-11-15 14:43 @655

Publicidad

Re: Control de acceso CGI::Session

Notapor explorer » 2011-03-29 17:57 @789

Claro, como ves en el código de ejemplo del load(), si la sesión está vacía, es cuando se debe crear una nueva sesión con new().

De todas maneras, hay varias formas de controlar esto. No hay porqué seguir el orden impuesto por los manuales, aunque casi siempre tengan razón.

¿No puedes reducir tu código a la mínima expresión, para publicarlo aquí, entero? Quita todo lo que no sea necesario y deja solo la parte de inicio del programa.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Control de acceso CGI::Session

Notapor noa86 » 2011-03-29 18:40 @820

Ahora mismo tengo el código así. ¿Sería correcto como he programado lo referente a control de sesiones? Sigo sin saber por qué no me funciona el método is_expired().

Necesito una solución...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. require("wei.conf.perl");
  4.  
  5. use DBI;
  6. use CGI::Session;
  7. use CGI ':standard';
  8. use CGI::Carp qw'fatalsToBrowser warningsToBrowser';
  9.  
  10. my $cgi = CGI->new();
  11.  
  12. $dbh = DBI->connect( "DBI:mysql:$bd:localhost", $user, $passwd )
  13.     or die( "Can't connect to db: ", $dbh->errstr );
  14. my $session = CGI::Session->load( "driver:MySQL", $cgi, { Handle => $dbh } )
  15.     or die CGI::Session->errstr();
  16.  
  17. if ( $session->is_expired ) {
  18.     print $cgi->start_html(),
  19.         $cgi->p("Your session timed out!"),
  20.         $cgi->end_html();
  21.     exit(0);
  22. }
  23.  
  24. if ( $session->is_empty ) {
  25.     $session = CGI::Session->new( "driver:MySQL", $cgi, { Handle => $dbh } );
  26.     $session->expire(10);
  27. }
  28.  
  29. print $session->header;
  30.  
  31. if ( not $session->param('~registrado') )
  32. {                                      # si el usuario no está registrado
  33.  
  34.     if ( my $nombre = $cgi->param('login_nombre') ) {
  35.         my $passwd = $cgi->param('login_passwd');
  36.  
  37.         if ( usuario_registrado( $nombre, $passwd ) ) {
  38.             $session->param( 'nombre',      $nombre );
  39.             $session->param( '~registrado', 1 );
  40.         }
  41.         else {
  42.             presenta_login('Usuario desconocido');
  43.             exit;
  44.         }
  45.     }
  46.     else {
  47.         presenta_login('Identifiquese');
  48.         exit;
  49.     }
  50. }
  51.  
  52. if ( $cgi->param('Desconectar') ) {
  53.     $session->clear( ['~registrado'] );
  54.  
  55.     print
  56.         start_html('Desconexión'),
  57.         h2('Se ha desconectado'),
  58.         hr(),
  59.         p("Adios, $nombre"),
  60.         end_html();
  61. }
  62. else {
  63.     print
  64.         start_html('Bienvenido'),
  65.         h2('Bienvenido'),
  66.         hr(),
  67.         p( "Bienvenido", $session->param('nombre') ),
  68.         hr(),
  69.         p( a( { -href => $cgi->url() . '?Desconectar=1' }, 'Desconectar' ) ),
  70.  
  71.         end_html();
  72.  
  73.     #continuación de pagina.
  74. }
  75.  
  76. sub usuario_registrado {
  77.     ...;
  78. }
  79.  
  80. sub presenta_login {
  81.     ...;
  82. }
  83.  
  84.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Última edición por noa86 el 2011-03-31 14:19 @638, editado 1 vez en total
noa86
Perlero nuevo
Perlero nuevo
 
Mensajes: 93
Registrado: 2010-11-15 14:43 @655

Re: Control de acceso CGI::Session

Notapor noa86 » 2011-03-31 08:17 @386

¿Nadie sabe por qué puede ser que no me funcione is_expired?
noa86
Perlero nuevo
Perlero nuevo
 
Mensajes: 93
Registrado: 2010-11-15 14:43 @655

Re: Control de acceso CGI::Session

Notapor explorer » 2011-03-31 09:58 @456

¿Para qué está la línea 17? ¿No vale con la 31?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Control de acceso CGI::Session

Notapor noa86 » 2011-03-31 10:19 @471

Lo que necesito es que cuando salga de la sesión porque el tiempo ha expirado, muestre un mensaje "Su tiempo ha expirado, ingrese de nuevo".

¿Hay alguna otra manera de hacer eso a parte del método is_expired() que no me funciona?

¿Alguien puede ayudarme por favor?
Última edición por noa86 el 2011-04-03 13:30 @604, editado 1 vez en total
noa86
Perlero nuevo
Perlero nuevo
 
Mensajes: 93
Registrado: 2010-11-15 14:43 @655

Re: Control de acceso CGI::Session

Notapor explorer » 2011-03-31 22:37 @984

Texto muy largo, que solo interesa el último ejemplo

El problema es el siguiente:

Cuando tu marcas un tiempo de expiración con expire(), ese tiempo se marca tanto en el fichero de sesión que se guarda en la base de datos, como en el tiempo de expiración de la cookie (galleta) que se manda al usuario.

Si el usuario accede dentro del tiempo asignado, aparecerá como registrado, pero si deja pasar ese tiempo (desde la última vez que se accedió al sistema), la galleta de su navegador habrá caducado, por lo que no se transmitirá al cgi... Para el cgi será como si se hubiera conectado un nuevo usuario, por lo que creará una nueva sesión con new().

En resumen: nunca nos enteraremos de si la sesión ha caducado, porque el usuario nunca nos transmitirá una cookie caducada (bueno, 'puede' darse el caso, alguna vez... depende de los relojes de cada ordenador).

Así que, por defecto, siempre recibiremos peticiones de sesiones conocidas o peticiones de nuevas sesiones. Nunca veremos que la función is_expired() sea cierta.

Este ejemplo funciona así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use CGI           qw':standard';
  7. use CGI::Session;
  8. use CGI::Carp     qw'fatalsToBrowser warningsToBrowser';
  9.  
  10. chdir '/home/explorer/public_html';     # directorio de trabajo
  11.  
  12. my $cgi = CGI->new;                     # creamos el objeto CGI
  13.  
  14. my $session                             # creamos el objeto CGI::Session
  15.     = CGI::Session->load(
  16.         "driver:file",
  17.         $cgi,
  18.         {Directory => './sesiones'}
  19.     );
  20.  
  21. die "ERROR: \$session indefinida\n" if not defined $session;
  22.  
  23. if ($session->is_expired) {             # ¿la sesión ha expirado?
  24.     print
  25.         $session->header,
  26.         $cgi->start_html,
  27.         cabeceras_http(),
  28.         $cgi->p("Su sesión ha expirado. Identifiquese de nuevo:"),
  29.         formulario(),
  30.         $cgi->end_html,
  31.         ;
  32.     terminar();
  33. }
  34.  
  35. if ($session->is_empty) {               # ¿la sesión está vacía?
  36.     $session = $session->new(           # creamos una nueva
  37.         "driver:file",
  38.         $cgi,
  39.         {Directory => './sesiones'}
  40.     ) or die "ERROR en la creación de nueva sesión: " .$session->errstr;
  41.  
  42.     $session->expire('60');             # le dejamos estar 60 segundos
  43. }
  44.                                         # vemos si se está autenticando
  45. my $usuario = $cgi->param('login_nombre') || '';
  46. my $passwd  = $cgi->param('login_passwd') || '';
  47.  
  48. if ($usuario and $passwd and usuario_verificado($usuario, $passwd)) {
  49.     $session->param('~registrado', 1);
  50.     $session->param('nombre', $usuario); # guardamos su nombre
  51. }
  52.  
  53. if (! $session->param('~registrado')) { # ¿es un usuario registrado?
  54.     print                               # No. Presentamos la página de registro
  55.         $session->header,
  56.         $cgi->start_html,
  57.         cabeceras_http(),
  58.         $cgi->p("Identifiquese:"),
  59.         formulario(),
  60.         $cgi->end_html,
  61.         ;
  62.     terminar();
  63. }
  64.  
  65. # Llegamos aquí cuando el usuario está registrado e identificado
  66. print                           # sí, presentamos una página normal
  67.     $session->header,
  68.     $cgi->start_html,
  69.     cabeceras_http(),
  70.     $cgi->p('Gracias por su visita, ' . $session->param('nombre'). '. Dispone de 60 segundos.'),
  71.     $cgi->end_html,
  72.     ;
  73.  
  74. ## Fin del programa
  75. terminar();
  76.  
  77. ### Subrutinas
  78. sub usuario_verificado {                # consulta si el usuario es real
  79.     return $_[0] eq 'JF' and $_[1] eq 'c12';
  80. }
  81.  
  82. sub formulario {                        # presenta un formulario muy simple
  83.     return
  84.         $cgi->start_form,
  85.         'Nombre: ',
  86.         $cgi->textfield('login_nombre'), br,
  87.         'Passwd: ',
  88.         $cgi->password_field('login_passwd'), br,
  89.         $cgi->submit,
  90.         $cgi->end_form,
  91.         ;
  92. }
  93.  
  94. sub cabeceras_http {
  95.     return
  96.         $cgi->p(
  97.             join $cgi->br, map { "$_ : " . $cgi->http($_) } sort $cgi->http()
  98.         )
  99.         ;
  100. }
  101.  
  102. sub terminar {
  103.     $session->flush();
  104.     CGI::Session->find('driver:file', sub {}, {Directory => './sesiones'} );            # Purgamos sesiones caducadas
  105.     exit(0);
  106. }
  107.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Básicamente:
  • Creamos el objeto CGI y el objeto CGI::Session, a partir del load()
  • Si la sesión ha expirado, se le presenta un mensaje de aviso y el formulario de entrada, y termina
  • Si la sesión está vacía, se crea una nueva sesión, con un tiempo de expiración de 60 segundos
  • Si el usuario nos está mandando las credenciales, comprobamos su validez
  • Si es un usuario valido (nos da nombre y contraseña) y verificado (le reconocemos), entonces lo marcamos con un parámetro llamado '~registrado' igual a 1 (el nombre del parámetro da igual)
  • Si el usuario no está registrado, entonces le presentamos el formulario de entrada y terminamos
  • Si sí lo está, le presentamos el resto del web (en este caso, una página sencilla)
  • Y terminamos

Como detalles importantes:
  • Este ejemplo difiere del tuyo en que estoy usando sesiones basadas en ficheros en disco, en lugar de usar una base de datos, pero el funcionamiento de la sesión es igual
  • A terminar() se le llama desde distintos puntos, pues tiene varias tareas que hacer: hace un flush(), que, realmente, en este ejemplo, no es necesario, porque el propio CGI::Session lo llamaría de forma automática, al salir del programa. Caso distinto es si guardáramos la sesión en una base de datos, como es tu caso: si la variable que almacena la conexión a la base de datos sale del contexto en que fue creada, la sesión quizás no pueda grabarse bien en la base de datos. Por ello se recomienda llamar a flush() antes de terminar el programa, en un sitio seguro dentro del programa, donde estemos seguros que aún tenemos control de la $session. Y una cosa más que hace terminar(): elimina las sesiones caducadas, con la ayuda de find(). Si no lo hiciéramos, se irían acumulando indefinidamente en disco o en la base de datos.
  • cabeceras_http() es una función de apoyo, para ver las cabeceras HTTP que el usuario nos manda a nuestro CGI.

En situaciones normales, esto es precisamente lo que queremos: mantener la sesión con el usuario, o pedirle que se autentifique. Así que este ejemplo vale para la gran mayoría de sitios web en los que queremos llevar un control de los usuarios que entran. Y la expiración del tiempo la da la propia expiración de la cookie que NO se transmite desde el usuario a nuestro cgi.

Ahora bien... este programa no hace lo tu que quieres...

Tu quieres que el programa cgi reconozca al usuario para decirle que su sesión ha expirado.

Eso implica que: el usuario se debe conectar a nuestro cgi con una cookie de sesión, y que encontremos que esa sesión ha caducado en nuestro sistema.

Fíjate que lo que estás pidiendo es muy especial: pocos sitios web lo tienen implementado así... la mayoría usan la primera técnica: si la cookie caduca, es que la sesión caduca.

Otros sitios web utilizan trucos para hacer lo que quieres.

Uno de ellos es el de transmitir dos cookies. Una de ellas contendrá un identificador con el que relacionaremos el nombre del usuario, cuando se registre. Y la otra nos servirá para el control del tiempo de sesión.

Así, cuando el usuario lleve un tiempo sin hacer nada en nuestro sitio web, la segunda cookie caducará y no se transmitirá, pero la primera sí se transmitirá (no caducará porque le hemos dado una fecha de expiración muy grande, como por ejemplo, 1 de abril del 2030). Entonces, ¿qué ocurre? Pues que el programa que recibe la primera cookie sabe quién es (el usuario que se conecta), pero como no recibe la cookie de control de tiempo, entonces sabe que la sesión ha expirado, por lo que mostrará un aviso al usuario (sabe quién es y sabe que la sesión ha caducado).

No sé si este es el comportamiento que quieres hacer o te vale con el primero, el básico. Si no quieres complicarlo, te recomiendo que te olvides de todo el tema de load() y de is_expired(). Simplemente, con hacer un new() al principio para crear la sesión, CGI::Session se dará cuenta de cuándo es una nueva sesión o de una sesión ya iniciada por el usuario. Solo te quedará hacer un expire() para marcar cuánto tiempo queremos que dure la sesión, y listo: si el usuario se conecta más allá del tiempo indicado, no transmitirá la cookie de sesión, así que para nosotros será como si se conectara de nuevo.

¿Te vale así, o prefieres el segundo comportamiento? ¿Aquel en el que sabemos quién es, aunque haya caducado la sesión?

Si queremos que se comporte de la segunda manera, tenemos que trabajar de forma distinta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use CGI           qw':standard';
  7. use CGI::Cookie;
  8. use CGI::Session;
  9. use CGI::Carp     qw'fatalsToBrowser warningsToBrowser';
  10.  
  11. my $tiempo_sesion = '10s';              # Tiempo que dura la sesión
  12.  
  13. chdir '/home/explorer/public_html';     # directorio de trabajo
  14.  
  15. my $cgi = CGI->new;                     # creamos el objeto CGI
  16.  
  17. my $session                             # creamos el objeto CGI::Session
  18.     = CGI::Session->load(
  19.         "driver:file",
  20.         $cgi,
  21.         {Directory => './sesiones'}
  22.     );
  23.  
  24. die "ERROR: \$session indefinida\n" if not defined $session;
  25.  
  26. my $cookie;
  27.  
  28.  
  29. if ($session->is_expired) {             # ¿la sesión ha expirado?
  30.     print
  31.         $cgi->header(),
  32.         $cgi->start_html,
  33.         cabeceras_http(),
  34.         $cgi->p("Su sesion ha expirado. Identifiquese de nuevo:"),
  35.         formulario(),
  36.         $cgi->end_html,
  37.         ;
  38.     terminar();
  39. }
  40.  
  41. if ($session->is_empty) {               # ¿la sesión está vacía?
  42.     $session = $session->new(           # creamos una nueva
  43.         "driver:file",
  44.         $cgi,
  45.         {Directory => './sesiones'}
  46.     ) or die "ERROR en la creación de nueva sesión: " .$session->errstr;
  47.  
  48.     $session->expire($tiempo_sesion);   # Tiempo de expiración de la sesión
  49. }
  50.  
  51. # Creamos una cookie con un tiempo de expiración superior al de sesión (una hora)
  52. $cookie = $cgi->cookie( -name => $session->name, -value => $session->id, -expires => '+1h');
  53.  
  54.                                         # vemos si se está autenticando
  55. my $usuario = $cgi->param('login_nombre') || '';
  56. my $passwd  = $cgi->param('login_passwd') || '';
  57.  
  58. if ($usuario and $passwd and usuario_verificado($usuario, $passwd)) {
  59.     $session->param('~registrado', 1);
  60.     $session->param('nombre', $usuario); # guardamos su nombre
  61. }
  62.  
  63. if (! $session->param('~registrado')) { # ¿es un usuario registrado?
  64.     print                               # No. Presentamos la página de registro
  65.         $session->header(-cookie=>$cookie),
  66.         $cgi->start_html,
  67.         cabeceras_http(),
  68.         $cgi->p("Identifiquese:"),
  69.         formulario(),
  70.         $cgi->end_html,
  71.         ;
  72.     terminar();
  73. }
  74.  
  75. # Llegamos aquí cuando el usuario está registrado e identificado
  76. print                           # sí, presentamos una página normal
  77.     $session->header(-cookie=>$cookie),
  78.     $cgi->start_html,
  79.     cabeceras_http(),
  80.     $cgi->p('Gracias por su visita, ' . $session->param('nombre'). ". Dispone de $tiempo_sesion."),
  81.     $cgi->end_html,
  82.     ;
  83.  
  84. ## Fin del programa
  85. terminar();
  86.  
  87. ### Subrutinas
  88. sub usuario_verificado {                # consulta si el usuario es real
  89.     return $_[0] eq 'JF' and $_[1] eq 'c12';
  90. }
  91.  
  92. sub formulario {                        # presenta un formulario muy simple
  93.     return
  94.         $cgi->start_form,
  95.         'Nombre: ',
  96.         $cgi->textfield('login_nombre'), br,
  97.         'Passwd: ',
  98.         $cgi->password_field('login_passwd'), br,
  99.         $cgi->submit,
  100.         $cgi->end_form,
  101.         ;
  102. }
  103.  
  104. sub cabeceras_http {
  105.     return
  106.         $cgi->p(
  107.             join $cgi->br, map { "$_ : " . $cgi->http($_) } sort $cgi->http()
  108.         )
  109.         ;
  110. }
  111.  
  112. sub terminar {
  113.     $session->flush();
  114.     CGI::Session->find('driver:file', sub {}, {Directory => './sesiones'} );            # Purgamos sesiones caducadas
  115.     exit(0);
  116. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Esta versión es casi idéntica a la anterior, pero hay unos pequeños cambios. Estos son los más importantes:
  • Línea 7: importamos el módulo CGI::Cookie
  • Línea 26: declaramos la variable global $cookie
  • Línea 51: creamos una cookie, usando el mismo nombre y el mismo id de sesión que el que utiliza CGI::Session, pero con la diferencia de que esta cookie tiene un tiempo de expiración mucho más largo: una hora
  • Línea 65 y 78: a la hora de enviar las cabeceras, enviamos nuestra propia $cookie. En realidad, lo que estamos haciendo es "machacar" la cookie que crea CGI::Session, con un tiempo de expiración marcado en la línea 48, por nuestra propia $cookie, con un tiempo de expiración de 1 h.
El resultado es el siguiente: el usuario se registra de forma normal. La cookie almacenada en su equipo expirará en una hora, pero la sesión, en el servidor, expirará mucho antes (10 s como ves en la línea 11). Si el usuario deja pasar esos diez segundos y vuelve a conectarse a nuestro cgi, su navegador transmitirá la cookie (no ha pasado una hora, por lo que no ha caducado). CGI::Session verá (en el load() de la línea 18) que hay una sesión correspondiente a la cookie que está recibiendo, pero, como han pasado más de diez segundos, la marca como expirada, y elimina la sesión (en el ejemplo, al ser ficheros, lo que hace es borrar el fichero de sesión). El programa entra por el if() de la línea 29 (is_expired() da verdadero), pero toda la información de la sesión se ha perdido (todos los parámetros almacenados en la sesión). Sale el aviso de que ha expirado y que se registre de nuevo.

Si el usuario, en vez de registrarse, recarga la página, entonces load() ya no encontrará una sesión correspondiente a la cookie que está recibiendo, porque borró la sesión hace un momento. Entonces, lo que ve el usuario es el mensaje directo de "Identifíquese", como si nunca hubiera entrado.

Bueno, esta es una forma de hacerlo, que se aproxima a lo que quieres hacer, pero no deja de ser una pequeña chapuza: estamos sobreescribiendo una cookie que ha fabricado CGI::Session por una fabricada por nosotros. Esto podría no funcionar si el autor de CGI::Session hace algún cambio importante en el código.

Hay una solución mejor: hacer que sea un parámetro de la sesión el que lleve el control del tiempo de expiración:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use CGI           qw':standard';
  7. use CGI::Session;
  8. use CGI::Carp     qw'fatalsToBrowser warningsToBrowser';
  9.  
  10. my $tiempo_sesion = '+1d';              # Tiempo que dura la sesión (máximo)
  11. my $tiempo_login  = '+10s';             # Tiempo que dura la sesión (identificado)
  12.  
  13. chdir '/home/explorer/public_html';     # directorio de trabajo
  14.  
  15. my $cgi = CGI->new;                     # creamos el objeto CGI
  16.  
  17. my $session                             # creamos el objeto CGI::Session
  18.     = CGI::Session->new('driver:file', $cgi, {Directory => './sesiones'});
  19.  
  20. die "ERROR: \$session indefinida\n" if not defined $session;
  21.  
  22. if ($session->is_new) {                 # ¿es una nueva sesión?
  23.     $session->expire($tiempo_sesion);   # Tiempo de expiración de la sesión (todo el día)
  24.  
  25.     print                               # Presentamos la página de registro
  26.         $session->header,
  27.         $cgi->start_html,
  28.         cabeceras_http(),
  29.         $cgi->p("Identifiquese:"),
  30.         formulario(),
  31.         $cgi->end_html,
  32.         ;
  33.  
  34.     terminar();
  35. }
  36.  
  37. my $usuario = $cgi->param('login_nombre') || '';        # Vemos si se está registrando
  38. my $passwd  = $cgi->param('login_passwd') || '';
  39.  
  40. if ($usuario and $passwd and usuario_verificado($usuario, $passwd)) {
  41.     $session->param('~registrado', 1);          # Lo marcamos como registrado
  42.     $session->expire('~registrado', $tiempo_login);     # Tiempo que dura la sesión (login)
  43.  
  44.     $session->param('nombre', $usuario);                # Guardamos su nombre
  45. }
  46.  
  47. if (! $session->param('~registrado')) {                 # ¿Ha pasado el tiempo de sesión login?
  48.  
  49.     my $usuario = $session->param('nombre') || '';      # Recuperamos su nombre
  50.     $usuario = ", $usuario" if $usuario;
  51.  
  52.     print
  53.         $cgi->header(),
  54.         $cgi->start_html,
  55.         cabeceras_http(),
  56.         $cgi->p("Su sesion ha expirado$usuario. Identifiquese de nuevo:"),
  57.         formulario(),
  58.         $cgi->end_html,
  59.         ;
  60.  
  61.     terminar();
  62. }
  63.  
  64. # Llegamos aquí cuando el usuario está registrado e identificado
  65. print                                                   # presentamos una página normal
  66.     $session->header,
  67.     $cgi->start_html,
  68.     cabeceras_http(),
  69.     $cgi->p('Gracias por su visita, ' . $session->param('nombre'). ". Dispone de $tiempo_login mas."),
  70.     $cgi->end_html,
  71.     ;
  72.  
  73. ## Fin del programa
  74. terminar();
  75.  
  76. ### Subrutinas
  77. sub usuario_verificado {                # consulta si el usuario es real
  78.     return $_[0] eq 'JF' and $_[1] eq 'c12';
  79. }
  80.  
  81. sub formulario {                        # presenta un formulario muy simple
  82.     return
  83.         $cgi->start_form,
  84.         'Nombre: ',
  85.         $cgi->textfield('login_nombre'), br,
  86.         'Passwd: ',
  87.         $cgi->password_field('login_passwd'), br,
  88.         $cgi->submit,
  89.         $cgi->end_form,
  90.         ;
  91. }
  92.  
  93. sub cabeceras_http {
  94.     return
  95.         $cgi->p(
  96.             join $cgi->br, map { "$_ : " . $cgi->http($_) } sort $cgi->http()
  97.         )
  98.         ;
  99. }
  100.  
  101. sub terminar {
  102.     $session->flush();
  103.     CGI::Session->find('driver:file', sub {}, {Directory => './sesiones'} );            # Purgamos sesiones caducadas
  104.     exit(0);  
  105. }
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Incluso queda más corto :lol:

Los cambios más importantes son:
  • Línea 18. Quitamos load() y lo cambiamos a new(). Él se encargara, o bien de cargar una sesión anterior, o de crear una nueva
  • Línea 22. Si la sesión es nueva, pues le damos un tiempo de expiración muy largo (todo el día). Este es el valor de expiración tanto para la sesión como para la cookie que se envía al usuario (y que nos devuelve). Le presentamos el formulario de registro al usuario y terminamos
  • Línea 42. (el truco) Le damos al parámetro '~registrado' un valor de 1 (podría ser otro valor mejor), y un tiempo de expiración de $tiempo_login. Este es el tiempo que queremos que esté activa la sesión de usuario sin que tenga que identificarse otra vez
  • Línea 47. Preguntamos si está registrado o no. '~registrado' indicará si, además de estar identificado en el sistema, ha caducado o no la sesión. Su no-presencia indicará que ha caducado, por lo que le avisamos al usuario, y terminamos

El resto es igual a lo que teníamos antes.

Espero que ahora haya quedado claro.

Falta la parte de borrar la sesión por indicación del usuario (delete()), pero es cuestión de poner otro if() en el lugar adecuando (por ejemplo, antes de ver si se está registrando).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Anterior

Volver a Módulos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados