Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I am using CGI::Session for data persistence. I use a common subroutine, get_session(), to either create a new session or retrieve an existing one (which has not expired). In 'login.cgi', get_session() will return a new session and in the subsequent scripts, (for example, form.cgi), it will return the existing session. This is working fine and I have no issues.

-------------------------------------------- login.cgi: -------------------------------------------- #!/usr/bin/perl -w use strict; use warnings; use lib "/path/to/lib/"; use CGI; use CGI::Session; # new query object my $cgi = CGI->new; # Get a new session my $session = get_session($cgi); print $session->header(); ... HTML template commands... ... print $template->output(); -------------------------------------------- form.cgi: -------------------------------------------- #!/usr/bin/perl -w use strict; use warnings; use lib "/path/to/lib/"; use CGI; use CGI::Session; # new query object my $cgi = CGI->new; # Get a new session my $session = get_session($cgi); print $session->header(); ... HTML template commands... ... print $template->output(); --------------------------------------------------------- get_session.pm (to create or retrieve a session ) --------------------------------------------------------- sub get_session { my $cgi = shift; my ($session, $exist_sess_id); # Query the cookie and retrieve existing session id, if exists $exist_sess_id = $query->cookie( "CGISESSID" ) or undef; # Retrieve or Create a session $session = CGI::Session->new( undef, $exist_sess_id, { Directory => '/usr/sessions' }) or die "can't create session: $!"; # Set expiration time $session->expire( "+10m" ); return $session; }

But, note that in the above code, if I close a session (let us say by killing the browser window), the session will be active for 10 minutes and if I call login.cgi before it expires, I still get the old session, which I wanted to eliminate. As per the new requirement, I should always get a new session in 'login.cgi'.

Hence, I created another sub,'delete_existing_session()', and called that before get_session() in 'login.cgi'. The idea is to get the existing session (if one is present and hasn't expired) and delete that before calling get_session(). Unfortunately, this didn't solve my problem as it still uses the old session for some reason. It seems that $session->delete() didn't do what I thought it would.

-------------------------------------------- login.cgi (modified) -------------------------------------------- #!/usr/bin/perl -w ... ... # new query object my $cgi = CGI->new; # Load and Delete existing session delete_existing_session($cgi); # Get a new session my $session = get_session($cgi); ... ... -------------------------------------------- delete_existing_session() -------------------------------------------- sub delete_existing_session { my $cgi = shift; my ($session, $exist_sess_id); # Query the cookie and retrieve existing session id, if exists $exist_sess_id = $cgi->cookie( "CGISESSID" ) or undef; # Load existing session $session = CGI::Session->load( $exist_sess_id ); # Delete the session $session->delete(); }

Can someone help me with this please?

Thanks, vgn

Replies are listed 'Best First'.
Re: Issues with creating a new CGI Session everytime at start-up
by oxone (Friar) on Aug 20, 2007 at 17:34 UTC
    There is a documented feature (some would call it a bug) with CGI::Session. Often it fails to write a change to disk, and you need to call the flush() method manually to help it along.

    So, it's possible that adding $session->flush() right after $session->delete() might solve your problem.

      Adding $session->flush() seem to have no effect.

      Now, I am trying to replicate the problem as a standalone script. Wondering if the cookie 'CGISESSID' has something to do with this behaviour although I would have expected $session->delete() and $session->flush() to have cleared the existing session from the disk.

        I found that $session in delete_existing_session() doesn't get the existing session in spite of providing the proper session_id to the sub, which means that $session->delete() doesn't do anything.

        ... # Load existing session $session = CGI::Session->load( $exist_sess_id ); $session->delete(); ... ...

        So, when the control returns back to get_session(), it recognizes the id that was passed in and retrieves the old one..

        I am wondering what makes $session = CGI::Session->load( $exist_sess_id ); to fail to retrieve the session.

        Any tips would be of great help. Thanks