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

I am trying to write a "member's area" for a web application that I am developing. I have followed the instructions in the CGI::Session Tutorial and Cookbook, but I think I am missing something. Actually I know I am, because I am having these problems, describe herein. After going to "index.html", the user submits to "login.cgi", which creates a new session, writes the session identification to a cookie in the user's browser and returns a page. The code below reflects that:
if(verify_password($username, $password)){ # write new HTTP session my $session = new CGI::Session(undef, undef, {Directory=>"/tmp"}); # inititialize session variables (expiry, etc) $session->param("~logged-in",1); #set logged in flag $session->param("username",$username); #write username in ses +sion $session->expires("~logged-in", "+5m"); #set 5 minute expirati +on # write sid to client cookie $cookie = $cgi->cookie(CGISESSID => $session->id); print $cgi->header(-cookie=>$cookie); print_success(); exit; } else { print_failure(); exit;}
The problem occurs when a user's session expires. They are sent back to "index.html" through "Location: index.html\n\n" in the HTTP header. The address bar still reports the location as being the referring page, however. So, when the user attempts to return to that script, (s)he is presented with the login prompt again. When the user reenters his/her information, they can once again freely navigate the site. Another interesting event is that if the user navigates "Back" from the second (erroneous) login prompt, and then attempts to visit the link again, they proceed. Below is the validation section of all the pages in the member's area.
#!/usr/bin/perl -wT use CGI; use CGI::Session; use CGI::Session qw/-ip-match/; use DBI; my $cgi = new CGI; my $session; my $anon = sub {$session->delete(); print"Location: /fwm/index.html\n\n"; exit(0);}; my $sid = $cgi->cookie("CGISESSID") || undef; $session = new CGI::Session(undef,$sid,{Directory=>'/tmp'}); &$anon unless $session->param("~logged-in"); # expired session $session->param("~logged-in",1); # refresh session
Below this code is all preprocessing for the page to be printed. The header that I print before the HTML is simply a "Content-type: text/html\n\n", because I don't want to write another cookie, or do I need to. Thanks in advance for the help.
amt

Replies are listed 'Best First'.
Re: CGI::Session Expiration Woes
by Arunbear (Prior) on Aug 10, 2004 at 16:50 UTC
    Try using an absolute url in your redirection code:
    print $cgi->redirect('http://somewhere.com/fwm/index.html');
    instead of
    print"Location: /fwm/index.html\n\n";
      Thanks Arunbear. This worked....for the time being.
      ::Cue ominous music::
      amt
Re: CGI::Session Expiration Woes
by danielcid (Scribe) on Aug 11, 2004 at 12:31 UTC
    The second problem, related to the back button, occurs because the browser re-post the old values to the login page, causing the user to re-authenticate. I read an article (don't remember where) that suggests the addition of a third page in the "login" sequence, to avoid this "feature" of some browsers...

    -DBC
      that's not quite what happens danielcid. They time out, they log in and go to the "login.cgi". Upon clicking the page they timed out on, it goes to "login.html". But if the user browses back to the "login.cgi" and clicks that link again, the user can navigate to the page. so it is more of a stutter step then a reposting problem, because I'm using mozilla and if i need to repost, it would prompt me to do so. amt.
Re: CGI::Session Expiration Woes
by jdtoronto (Prior) on Aug 11, 2004 at 14:54 UTC
    My solution to the same problem ( I use CGI::Session with CGI::Application in all my applications ) is to remember what the user asked for before they were asked to revalidate. Each time the user makes a menu selection - and goes to the dispatcher - I check for expiration, if the session has expired than I save the requested option oin the session and then attempt to re-validate the session. Once they are validated, they then get taken to the place they asked to go.

    jdtoronto

      I'd like to see that code, if you wouldn't mind. I would assume you use merlyn's two-tier sessioning structure?

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested