Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

CGI::Session - non-stop session creation problem

by Stenyj (Beadle)
on Apr 06, 2005 at 03:53 UTC ( [id://445164]=perlquestion: print w/replies, xml ) Need Help??

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

Please forgive me for this stupid question, but I'm hoping for some insight on how some of you more experienced programmers use CGI::Session.

I'm currently using this in my scripts:
my $sid = $foo->cookie('main') || undef; my $session = new CGI::Session(undef, $sid, {Directory=>'c:/apache/ses +sions'});

When a user logged in, the session ID was stored in the cookie 'main'. I'm encountering a few problems though. Many of my pages are used by users both logged in and not logged in. I want to use sessions for those logged in, but NOT create a session for those who aren't.

I was using:
if ($sid) { $session = new CGI::Session(undef, $sid, {Directory=>'c:/apache/se +ssions'}); # a bunch of code that grabbed data from the session }

The problem here is that $sid could exists, even if the sessions has expired but the cookie hasn't (for whatever reason that may happen), resulting in a new session being created every single time the page is loaded. The last thing I need is thousands of session files being generated for no good reason ;-p

So I'm *guessing* that there's some variation of this line:
$session = new CGI::Session(undef, $sid, {Directory=>'c:/apache/sessions'});

where it won't create a new session if it doesn't exist, or something of that sort.

The 3 tutorials that I've printed and previously used for reference don't seem to address this problem.

Can anyone bail me out here?

Any help/advice/suggestions would be greatly appreciate.

Thx,

Stenyj

Replies are listed 'Best First'.
Re: CGI::Session - non-stop session creation problem
by Tanktalus (Canon) on Apr 06, 2005 at 04:02 UTC

    How do you determine someone is logged in or not?

    if ($sid) { $session = CGI::Session->new(undef, $sid, {Directory => 'c:/apache/s +essions'}); if (! logged_in($session)) { $session->delete(); } }

    Or something like that.

      Is that an efficient way of handling it though? Seems unecessary & a waste to create and then immediately delete a session every time a page is loaded, unless the user is logged in.

      I appreciate the feedback. Keep it comin' :-)

      Stenyj

        Put your sessions on a fast disk. Your operating system and/or filesystem cache and/or hard disk cache will optimise this away to never touching your hard disk.

        I insert another layer. Using CGI::Session::DB2, I have the hard disk cache, the filesystem cache, the database cache, and probably something else I'm missing, all pretty much keeping me safe. ;-)

        Also, I'm not even sure that CGI::Session will save anything if the session is deleted immediately like this - it should save during the destruction of the object, where you've already marked it for deletion. So, even though the above says that your physical disk is never touched, this says it likely isn't even asked.

Re: CGI::Session - non-stop session creation problem
by Cody Pendant (Prior) on Apr 06, 2005 at 06:30 UTC
    I'm confused, but surely your problem is that you've got both CGI::Session and some other code setting cookies which expire at different times?

    You say for instance "The problem here is that $sid could exists, even if the sessions has expired but the cookie hasn't (for whatever reason that may happen)" -- why would that happen if you had only one session-management system?

    Talk us through it. People log in, and some code sets the "main" cookie. What code does that?



    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
    =~y~b-v~a-z~s; print
      my $session = new CGI::Session(undef, $empty, {Directory=>"c:/apac +he/sessions"}); $session->expire('+18h'); $session->param("userID", $userID); my $cookie = $foo->cookie(-name => 'main', -value => $session->id, -expires => '+30d', -path => '/'); print $foo->header(-cookie => $cookie);

      So basically, someone logs in & a cookie is set.

      Then, logged in or not, people visit pages that have the following code:
      my $sid = $foo->cookie('main') || undef; my $session = new CGI::Session(undef, $sid, {Directory=>'c:/apache/ses +sions'});
      The problem is that, regardless of whether or not the cookie exists, a new session is created.
      The ONLY time I want a session created is in the login script, when the cookie & session should be created.
      AFTER that, I would simply like to grab the session data *IF* one exists.

      Right now, every time a page is loaded, if a session doesn't exists one is created... and then because a cookie isn't stored every time a page is visisted, the next page that's loaded creates a new session because a cookie containing the session data from the previous page wasn't stored. I don't want it to create a new sessions/cookie on every page, only on the login script.

      Any thoughts/suggestions?

      Stenyj
Re: CGI::Session - non-stop session creation problem
by Miguel (Friar) on Apr 07, 2005 at 11:26 UTC
    A short but functional example:
    #!/usr/bin/perl -Tw use strict; use CGI; use CGI::Session qw/ip-match/; my $q = new CGI; my $name = "name"; my $password = "password"; my $f_name = $q->param("name") || ""; my $f_password = $q->param("password") || ""; my $session = new CGI::Session(undef,$q,{Directory=>'/tmp'}); $session->expire('+1h'); my $sessionid=$q->cookie("cgisessid")||$session->param("_SESSION_ID"); my $cookie_id = $q->cookie(CGISESSID=>$session->id); $session->delete() if $q->param("out"); if (!$session->param("name") && ValidateLogin($f_name,$f_password) == 0) { Form(); } else { LogedIn(); } sub Form { print $q->header, $q->start_html, $q->start_form, "Name: ", $q->textfield({NAME=>'name',OVERRIDE=>1}), $q->br, "Password: ", $q->password_field({NAME=>'password',OVERRIDE=>1}), $q->br, $q->submit("Login"), $q->end_form, "Sesson ID: ", $session->id, $q->p,"HINT: Use 'name' and 'password' to login",$q->end_html; } sub LogedIn { $session->param("name",$q->param("name")); print $q->header({COOKIE=>$cookie_id}), $q->start_html, "LoggedIn", $q->br, "SESSION(id): ", $session->id, $q->br, "SESSION(name): ", $session->param("name"), $q->br; print $q->start_form, $q->hidden({NAME=>'out',VALUE=>1}), $q->submit("LogOut"), $q->end_form, $q->end_html; } sub ValidateLogin { my ($n,$p) = @_; $n ne $name && $p ne $password ? 0 : 1; }

    Hope it helps.

Re: CGI::Session - non-stop session creation problem
by Miguel (Friar) on Apr 07, 2005 at 01:44 UTC
    If I understand your question, you could do:

    1. A user enters your website;
    2. Check if $session->param("name") exists; IF exists is a privileged user ELSE is a visitor;
    3. If is a visitor create a (normal) session variable and store a cookie;
    4. If visitor logs in, you need to add a session variable, like, for example:

    $session->param("name", $cgi->param("name"));
    and the visitor 'upgrades' to 'privileged user'.

      That's basically what I want to do, but what I can't figure out is how to initiate $session without it creating a new one if it doesn't exist.
      ie.
      my $sid = $foo->cookie('main') || undef; my $session = new CGI::Session(undef, $sid, {Directory=>'c:/apache/ses +sions'}); if ($session->param("alias")) { .... #grab data from session }

      That is creating the session if one with the sid stored in the cookie 'main' doesn't exist...
      Is there a way to simply attempt to grab a session, and if it doesn't exists, leave $session null?

        I take it you didn't like my previous solution. I'm not entirely sure why.

        my $sid = $foo->cookie('main') || undef; my $session; # = undef if (is_logged_in()) { $session = CGI::Session->new(undef, $sid, {Directory => 'c:/apache/s +essions'}); }
        What still is not clear to me is how you determine whether someone is logged in or not. If that is just by the existance of the "main" cookie, then "is_logged_in()" is simply the existance of $sid:
        my $sid = $foo->cookie('main') || undef; my $session; # = undef if (defined $sid) { $session = CGI::Session->new(undef, $sid, {Directory => 'c:/apache/s +essions'}); }
        Of course, in the code that logs in, you'll need to create a new session at that time, so you have a sid to put into the main cookie. But I don't think that's the problem you're having (yet).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://445164]
Approved by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-24 04:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found