• Publicidad

Problema con control de sesiones

Todo lo relacionado con el desarrollo Web con Perl: desde CGI hasta Mojolicious

Problema con control de sesiones

Notapor ridomil » 2012-05-08 08:00 @375

Hola chicos, tengo un problema con un cgi a la hora de controlar las sesiones.

Utilizo un archivo que llamo sesiones.cgi que crea la sesión y luego comprueba los niveles de administración del usuario autenticado. Ese archivo lo llamo desde otro cgi, el que pinta en el navegador el html.

Pues bien, resulta que me funciona en todos mis cgi menos en uno concretamente y soy incapaz de determinar el porqué.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. require $ENV{'DOCUMENT_ROOT'}."/design/cgi-local/sesiones.cgi";
  4.  
  5. our($session);
  6.  
  7. use strict;
  8. use warnings;
  9. use subs;
  10.  
  11. use lib "../Clases";
  12.  
  13. use ListarPropuestas;
  14.  
  15. use CGI;
  16.  
  17. use CGI::Carp qw(fatalsToBrowser);
  18.  
  19. my $q = CGI -> new();
  20.  
  21. my %Variables = $q -> Vars;
  22.  
  23.  
  24.  
  25. print "Content-type: text/html; charset=utf-8 \n\n";
  26.  
  27. if($session && esAdministradorGeneral()){
  28.     guardarLog("[ListarDocumentos] :  Existe una sesion ... ");
  29. }
  30. else
  31. {
  32.     guardarLog("[ListarDocumentos] : No existe una sesión ...");
  33. }
  34.  
  35.  
  36.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El gran problema es que no crea el objeto hash de tipo Session, y el document root sí que está correcto que es donde está el archivo que previamente os comentaba que empleo para todos los demás cgi. Es una cosa bastante rara y no logro descubrir qué pasa...

Muchas gracias de antemano.
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Publicidad

Re: Problema con control de sesiones

Notapor explorer » 2012-05-08 09:14 @426

Pero... a ver... en la línea 5 declaras que hay una variable global llamada $session. Luego, en la 27 miras a ver cuál es su valor, pero, ¿dónde ha sido definido su valor?

Por otra parte, ya que usas el módulo CGI, puedes sustituir la línea 25 por esta otra:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print header(-type=>'text/html', -charset=>'utf-8');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema con control de sesiones

Notapor ridomil » 2012-05-09 01:54 @121

Muy buenas, explorer.

El valor de la variable $session está en el otro .cgi, el que controla las sesiones. En ese cgi uso el CGI::Session y hago el new() de la sesión. En cuanto a lo de la línea 25, sí, ya me he fijado en otros post que no estoy utilizando todas las características de Perl como debería en cuanto a la escritura del HTML.

Este es un trozo del archivo donde controlo las sesiones y los permisos según el tipo de usuario:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # package Sesiones;
  2.  
  3. use CGI;
  4. use CGI::Session;
  5.  
  6. require $ENV{'DOCUMENT_ROOT'}."/design/cgi-local/subrutinas.cgi";
  7. require $ENV{'DOCUMENT_ROOT'}."/design/cgi-local/parametros_site.cgi";
  8.  
  9. # print "Content-type: text/html  charset=utf-8\n\n\n\n";
  10.  
  11. our ($session);
  12. our ($llamadaFuncion);
  13.  
  14. $llamadaFuncion = "pintarError";
  15.  
  16. $q=new CGI;
  17. $Error='';
  18. $tiene_permisos=0;
  19. $recarga="";
  20.  
  21. #si existe una cookie de nombre 'legislado'
  22. if ($q->cookie(-name=>'legislado')) {
  23.         $cookie=$q->cookie(-name=>'legislado');
  24.         $session = new CGI::Session("driver:File",$cookie,{'Directory'=>$Dir_Sesiones});
  25.         #$session->expires('+20m');
  26.         #$cookie = $q->cookie(-name=>'legislado', -value=>$session->id($cookie), -expires=>'+2h', -path=>'/');
  27.         #$cookie = $q->cookie(-name=>'legislado', -value=>$session->id($cookie), -path=>'/');
  28.        
  29.         if(esZonaPublica() eq 1 || tienePermiso() eq 1 || esParaUsuariosRegistrados() eq 1){$tiene_permisos=1;}
  30.         else{ $Error=0;}
  31.        
  32. }else{
  33.  
  34. ....
  35.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Problema con control de sesiones

Notapor explorer » 2012-05-09 03:07 @171

Bueno, pues en ese caso... probaría a intercambiar las líneas 3 y 5, es decir: Declarar primero la variable con el our(), y luego llamar a sesiones.cgi.

Y si eso no funciona, entonces empezaría a sospechar que el problema está en sesiones.cgi.

Si dices que tienes otros programas iguales que sí funcionen, entonces hay que mirar en las condiciones en las que se ejecutan: quizás no estén guardando las sesiones en disco, el navegador del usuario no está recogiendo las cookies...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema con control de sesiones

Notapor ridomil » 2012-05-11 02:10 @132

Nada, no encuentro un motivo para que no funcione.

¿Cómo controlas tu el tema de las sesiones? ¿Utilizas algún paquete o algún método concreto?

Estoy pensando en reescribir el sesiones.cgi que es el que las controla, aunque a mi me parece que de esto no puede ser ya que en los otros casos funciona, pero ya no sé muy bien qué hacer...
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Problema con control de sesiones

Notapor explorer » 2012-05-11 07:35 @358

Yo, hasta ahora, usaba el entorno de programación de CGI::Application, pero es muy posible que mis próximos proyectos sean en Mojolicious. CGI::Application está construido por encima de CGI, CGI::Session, etc., con la que se pueden construir grandes proyectos, de forma estructurada. Aunque, como todo framework web, es necesario leer mucho para entender su funcionamiento y espacio de nombres. (Sí, en Mojolicious es más sencillo. Más detalles).

El caso es que con CGI::Session se debería poder tener un sistema básico de gestión de sesiones, y de forma fácil, según aparece en su sinopsis. Yo sí que he hecho unas cuantas páginas así, con este módulo.

Tienes también CGI::Session::Tutorial, con todo mucho más explicado. Hay dos scripts de ejemplo.

Si te ha funcionado en otras situaciones, el problema no será sesiones.cgi, sino a) el programa, o b) el entorno donde está el programa.

Dices que lo has mirado todo en el programa. ¿Has probado en dejarlo en la mínima expresión, a ver qué pasa? (solo crear/leer las sesiones). ¿Seguro que se ejecuta bien? ¿No sale nada raro en el error.log del servidor web?

Si pones un CGI::Carp tal y como lo pongo en mi CGI mínimo, los posibles errores saldrán en la pantalla del navegador.

En el segundo caso, el entorno... ¿el programa tiene permisos de escritura/registro de las sesiones? Recuerda que es el usuario que ejecuta el servidor web el que ejecuta el cgi, y por lo tanto, depedenderá de los permisos de escritura en el directorio donde se encuentren las sesiones, o poder hacer consultas a las bases de datos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema con control de sesiones

Notapor ridomil » 2012-05-21 03:23 @183

Buenas. El problema todavía no he conseguido resolverlo pero aislando me he dado cuenta que si quito el use del .pm la sesión se conserva perfectamente. Me explico, este es el archivo cgi:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use lib "../Clases";
  4.  
  5. use strict;
  6. use warnings;
  7. #Se envian los errores al navegador
  8. use CGI::Carp qw(fatalsToBrowser);
  9. #Modulo CGI
  10. use CGI;
  11. #Codificación UTF8
  12. binmode(STDOUT, ":utf8");
  13.  
  14. my $q = new CGI;
  15.  
  16.  
  17. require $ENV{'DOCUMENT_ROOT'}."/design/cgi-local/sesiones.cgi";
  18.  
  19.  
  20. our ($session);
  21.  
  22.  
  23. if($session){
  24.         guardarLog("Existe una sesión ........................................");
  25. }else{
  26.         guardarLog("No existe una sesión**************************************");
  27. }
  28.  
  29.  
  30.  
  31. guardarLog("Valor de la sesión en [MOSTRAR_EDITOR_CGI] ------------------------>".$session);
  32.  
  33.  
  34. use EditorXML;
  35.  
  36.  
  37. my %Variables = $q -> Vars;
  38.  
  39.  
  40. ################# Recogida de parámetros del formulario #######################
  41. # Método de envío de parámetros
  42. my $metodo = $ENV{'REQUEST_METHOD'};
  43.  
  44.  
  45. sub guardarLog
  46. {
  47.         my ($texto) = @_;
  48.         open (MiFichero, ">>./log.txt");
  49.         print MiFichero localtime(time)." ".$texto."\n";
  50.         close (MiFichero);
  51. }
  52.  
  53. my $datos;
  54. # Recoger los datos
  55. # según método
  56. if ($metodo eq "GET")
  57. {
  58.     $datos = $ENV{'QUERY_STRING'};
  59. }
  60. else
  61. {
  62.    read(STDIN, $datos, $ENV{'CONTENT_LENGTH'});
  63. }
  64.  
  65. my @paresValores = split (/&/,$datos);
  66. my %formDatos = ();
  67.  
  68.  
  69.  
  70. foreach my $par (@paresValores) {
  71.     my ($campo, $valor) = split (/=/,$par);
  72.     $valor =~ tr/+/ /;
  73.     $valor =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
  74.     $formDatos{$campo} = $valor;
  75.    
  76. }
  77. ....
  78.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


y enlaza con un .pm que tiene unas 6mil lineas que en realidad solo muestra el formulario y posteriormente se encarga de tareas de inserción, borrado y actualización en BD. No sé si podrías intuir qué puede hacer el .pm para destruir la sesión...

Este es un trozo del mismo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package EditorXML;
  2.  
  3. use strict;
  4. use Switch;
  5. use warnings;
  6. use DBD::mysql;
  7. use DBI;
  8. use XML::LibXML;
  9. use XML::LibXML::XPathContext;
  10. use File::Basename;
  11. use File::Copy;
  12. use HTML::Entities;
  13.  
  14. # use lib "../";
  15.  
  16. # use lib "../../Solr";
  17.  
  18. use lib "./";
  19.  
  20. use CGI::Carp qw(fatalsToBrowser);
  21.  
  22. binmode(STDOUT, ":utf8");
  23.  
  24. use InsercionBDSumarios;
  25.  
  26. use ArbolThesauro;
  27.  
  28. use InsercionBDSumarios;
  29.  
  30. use ParserNivel4;
  31.  
  32. sub new
  33. {
  34.         my $class = shift;                   # clase que representa
  35.         # my $class = ref($class) || $class; # averiguo clase
  36.         my $self = {};
  37.        
  38.         $self -> {_login} = undef;
  39.  
  40.         $self -> {_password} = undef;
  41.  
  42.         $self -> {_nombreBD} = undef;
  43.        
  44.         $self -> {_motorBD} = undef;
  45.        
  46.         $self -> {_host} = undef;
  47.        
  48.         $self -> {_dsn} = undef;
  49.        
  50.         $self -> {_dsnBDSumarios} = undef;
  51.        
  52.         $self -> {_dsnBDUsuarios} = undef;
  53.        
  54.         $self -> {_conexion} = undef;
  55.        
  56.         $self -> {_conexionBDSumarios} = undef;
  57.        
  58.         $self -> {_conexionBDUsuarios} = undef;
  59.        
  60.         $self -> {_manejador} = undef;
  61.        
  62.         $self -> {_manejadorBDSumarios} = undef;
  63.        
  64.         $self -> {_manejadorBDUsuarios} = undef;
  65.        
  66.         $self -> {_charset} = undef;
  67.        
  68. ....
  69.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Es decir, si yo comento la línea use EditorXML la sesión va correctamente.

La verdad es que es un tema bastante raro y me está escamando bastante. A ver si se os ocurre algún motivo por el que pueda estar pasando esto. Yo, ni idea...
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Problema con control de sesiones

Notapor ridomil » 2012-05-21 04:43 @238

Bien, he estado haciendo pruebas intentando recuperar la sesión a partir de la cookie tal y como dicen en CPAN, pero en realidad me crea una sesión nueva que nada tiene que ver con la que está activa. Además al hacer el CGI:Session me ignora el require de arriba del fichero de Sesiones y los métodos como esAdministrador() no me van... A mí me está pegando la risa vamos... No entiendo nada.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $sid = $cgi->cookie('CGISESSID') || $cgi->param('CGISESSID') || undef;
  2.     $session = new CGI::Session(undef, $sid, {Directory=>'/tmp'});
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Entiendo que CGISESSID es el nombre que le da al id cuando crea la cookie o es una palabra reservada para recuperar este...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $cookie = $q->cookie(-name=>"legislado", -value=>$session->id(), -expires=>'+1h', -path=>'/');
  2.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


en mi caso sería algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $sid = $q ->cookie("value") || undef;
  2. my $session = new CGI::Session(undef,$sid,{'Directory'=>$Dir_Sesiones});
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Problema con control de sesiones

Notapor ridomil » 2012-05-21 06:24 @308

se recupera a traves de CGISESSID así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   $sid = $cgi->cookie("CGISESSID") || undef;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Lo del value no sirve.
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Problema con control de sesiones

Notapor explorer » 2012-05-21 06:59 @333

Lo que te pasa a ti, también me ha pasado a mi. Me volvía loco preguntándome por qué se creaba sesiones nuevas, si los archivos de las cookies y de las sesiones estaban presentes...

Unas veces eran debidos a que no indica el tiempo de vida de la sesión, o el tiempo de supervivencia de la cookie, otras veces porque no indicaba bien la ruta al directorio de sesiones... En fin, son cosas variadas.

Entonces, no queda más remedio que leerse el tutorial, pero... al principio está lleno de "trampas".

Por ejemplo, dedica tiempo a hablarte de 'CGISESSID', pero en realidad, no necesitas indicar nada en tu programa, porque ese es el valor por defecto que quieres y que vas a usar. Así que, aunque en el tutorial habla mucho de cómo recuperar ese nombre o como cambiarle o cómo usarle, al final, no importa.

Otra trampa es la sección Getting Started. Se supone que ahí vienen los pasos para crear una sesión o leer una sesión, pero en realidad nos lía mucho, porque se entretiene en explicar cómo crear una sesión, cuando en realidad lo que nos interesa es cómo acceder a una sesión ya creada.

Y lo mismo, más tarde, habla de cómo crear la cookie, de cómo enviarla al usuario, etc... cuando todo se reduce a una línea (que también pone al final de la sección).

Resumen: dado un cgi en Perl que hace uso del módulo CGI, para tener soporte de sesiones con CGI::Session, solo hay que poner estas líneas al principio:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $cgi      = new CGI;                                               # nuevo objeto CGI
my $session  = new CGI::Session(undef, $cgi, { Directory=>"/tmp" } ); # nuevo objeto CGI::Session
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y luego, a la hora de sacar los datos en la ventana del navegador del usuario, acordarse de cambiar la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$cgi->header();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$session->header();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Nada de 'CGISESSID', nada de cookies.

¡Ojo!, que en algunos ejemplos verás que en vez de usar new CGI::Session usan CGI::Session->load(), como en el ejemplo del propio autor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $session = CGI::Session->load() or die CGI::Session->errstr;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Los dos hacen lo mismo: cargan una sesión si ya existe, pero en el caso de new(), además, la crea de forma automática en caso de que no existiese. Según lo que quieras hacer, deberás usar una u otra. Por ejemplo, querrás que el usuario se identifique antes de pasar al resto de la aplicación, así que puedes hacer un load(), y si falla, saltar al formulario de registro. O si es el caso de que no hay identificación, y que quieres que haya control de sesión en todo momento, pues usas new(). El último ejemplo enlazado antes es bastante bueno.

Y lo más insidioso: hay una página que se llama CGI::Session::CookBook, que solo está en una distribución antigua de CGI::Session, y que si no sabes cómo se llama, no la ves. En ese documento vienen cinco escenarios típicos, y que seguro que alguno de ellos se ajusta a lo que quieres hacer. Pero... recuerda que es un documento antiguo, por lo que algunas cosas han cambiado (sobre todo, hay nuevas funciones que ahorran código, como lo del $session->header).

Una cosa muy importante...

Si estás usando el módulo CGI, no necesitas NADA del código que tienes puesto entre las líneas 53 a 76... porque TODO eso ya lo hace la línea 37. Mejor dicho, la sola creación del objeto $cgi ya es suficiente para que CGI.pm extraiga el QUERY_STRING o lea desde la entrada estándar, parta la información por el delimitador '&', convierta los '+' en espacios, realice la conversión de caracteres codificados en la forma %XX, etc... Todo eso ya lo hace CGI.pm de forma automática. Tu solo tienes que poner la línea 37 para acceder a todos los argumentos que el usuario te pasa. Es más: ni siquiera te hace falta llamar a Vars(). Con ir llamando a param() con el nombre del argumento que quieres leer, te vale (siempre y cuando te sepas los nombres de todos los argumentos, claro).

Tienes otro artículo aquí (en inglés), con un buen resumen de todo esto, aunque sea de hace 9 años ;)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Web

¿Quién está conectado?

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