Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Cookie->fetch problem

by tultalk (Monk)
on Mar 09, 2017 at 15:41 UTC ( [id://1184038]=perlquestion: print w/replies, xml ) Need Help??

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

Hi: I am asking here as a last resort. I have this little subroutine that I am trying to recover cookie info to calling routine to determine whether use is logged in. The SID gets stored in the session table each time I log in. Over and over. This subroutine returns 0 on each attempt This warn("GetUserSessionCookie SID: $sid"); posts to error log: GetUserSessionCookie sessionname: '' at /home/jalamior/www/httpsdocs/cgi-bin/lib/perl/manageusers.pm line 673. I have seen fetch two different ways in literature CGI::Cookie->fetch. and fetch CGI::Cookie; ?????? Neither seems to work Since my $sessionname = 'CGISESSID'; is defined as global in the module, I am assuming that this code will recover only the cookie info associated with that name. Brain dead. Thanks

sub GetUserSessionCookie { warn("Entered GetUserSessionCookie"); use CGI qw/:standard/; # fetch existing cookies my %cookies = CGI::Cookie->fetch; warn(%cookies); my $sid; # warn("GetUserSessionCookie sessionname: '$cookies{$sessionname}'" +); if ($cookies{$sessionname}) { $sid = $cookies{$sessionname}->value; warn("GetUserSessionCookie SID: $sid"); } else{ $sid = 0; } return $sid; }

Replies are listed 'Best First'.
Re: Cookie->fetch problem
by Eily (Monsignor) on Mar 09, 2017 at 15:53 UTC

    This warn("GetUserSessionCookie SID: $sid"); posts to error log: GetUserSessionCookie sessionname: ''
    The message inside the warn and the actual log are distinct: one contains "SID", the other "sessionname". The warning message that does contain "sessionname" is commented out in your code. So either you are not modifying the file that is actually executed, or you gave us the wrong code.

      I copied the code at the wrong time. I have commented that in and out. Also where I set $sid to 0 was for testing also. I did set the $sid = '12ba7ce0cfeeae8e8a934af6724910e9'; which I copied from the cookie I am interested in and it proceeded to assume I was logged. The calling code just check ne 0 so anything ne 0 would have the same effect
      sub ProcessLoginRequest { my ($query) = @_; my $status = 0; # $sessionname = 'CGISESSID'; # my %cookies = CGI::Cookie->fetch; # my $sid = $cookies{$sessionname}->value; my $sid = GetUserSessionCookie(); warn("ProcessLoginRequest Query: '$query'"); warn("ProcessLoginRequest SID from cookie: '$sid'"); #Check if it got valid return from fetch cookie if ($sid ne 0){ $status = 1;

      But later I compare against the stored session ID.

      #--------------------------------------------------------------------- +---------- # FUNCTION: OpenSession($dbh, $sid) # Opens existing session or creates new depending on $sid #--------------------------------------------------------------------- +---------- sub OpenSession{ my ($dbh, $sid)= @_; $session = new CGI::Session("driver:MySQL", $sid, {Handle=>$dbh, Lo +ckHandle=>$dbh}); return $session; }
      Thanks

        OK. Then here's what you can do:
        1) Fix your original post's formatting (ie: add <p> tags). See Markup in the Monastery
        2) Add use Data::Dumper; at the top of your file, and turn warn %cookies; into warn Dumper \%cookies;, you'll get a clearer view of what fetch() returns.

Re: Cookie->fetch problem
by kennethk (Abbot) on Mar 09, 2017 at 15:49 UTC
    Have you checked what the cookies look like from the client side? You should be able to see them from developer tools built into any browser (RIP Firebug). It's possible that the system is not using a cookie mechanism for session tracking.

    I don't see any obvious errors with your attempt to interrogate the cookies. (Update: But Eily did)


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      "First ask yourself `How would I do this without a computer?' Then have the computer do it the same way" Well that is indeed a strange response. I guess I would get on my horse and rise into town to figure out which way is up. Seiously, I do not understand your response at all.
        That's not a response, it's a signature.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Cookie->fetch problem
by huck (Prior) on Mar 09, 2017 at 21:14 UTC

    Ok, do you remember the code i said you should try in Re^3: Sessions Questions? Still works just fine, i refreshed it It may have confused you because rather than the name of CGISESSID that CGI::Session uses my cookie was instead named TSSID. To get the current cookie i used my $tssid  = $q->cookie('TSSID');. while my %cookies = CGI::Cookie->fetch; $sid = $cookies{$sessionname}->value; is another valid way to do it, it will only work if $sessionname='CGISESSID';, you say that is true, but have you proved it?

    Lets review the code you have exposed so far here.

    sub GetUserSessionCookie { warn("Entered GetUserSessionCookie"); use CGI qw/:standard/; # fetch existing cookies my %cookies = CGI::Cookie->fetch; warn(%cookies); my $sid; # warn("GetUserSessionCookie sessionname: '$cookies{$sessionname}'" +); if ($cookies{$sessionname}) { $sid = $cookies{$sessionname}->value; warn("GetUserSessionCookie SID: $sid"); } else{ $sid = 0; } return $sid; } sub ProcessLoginRequest { my ($query) = @_; my $status = 0; # $sessionname = 'CGISESSID'; # my %cookies = CGI::Cookie->fetch; # my $sid = $cookies{$sessionname}->value; my $sid = GetUserSessionCookie(); warn("ProcessLoginRequest Query: '$query'"); warn("ProcessLoginRequest SID from cookie: '$sid'"); #Check if it got valid return from fetch cookie if ($sid ne 0){ $status = 1; ... end missing
    Do you see $sessionname getting set? to anything? Well there is a commented out statement. You have a habit of using "global-lexical" variables, (if i just said global someone would harp "they are not in $MAIN::, so they are lexical", so global-lexical means they are defined with a my but their scope is global). You may not have even set $sessionname or it is not the name of a cookie, which means if ($cookies{$sessionname}) { fails, and you will never see  warn("GetUserSessionCookie SID: $sid"); To make sure that $sessioname is set add warn("GetUserSessionCookie sessionname: '$sessionname'"); to the top of GetUserSessionCookie. (note NOT $cookies{$sessionname} like your commented out code uses, just $sessionname)

    if $sessionname='CGISESSID'; Why else might if ($cookies{$sessionname}) { fail? that would also happen if the user did not have the CGISESSID cookie set, because it expired or was deleted. In this case you set $sid=0; This is a bad thing to do for if that is the $sid you pass in $session  = new CGI::Session("driver:MySQL", $sid, {Handle=>$dbh, LockHandle=>$dbh});. CGI::Session will create a new session there if $sid is undef, but i bet (untested) that if $sid is 0 it considers it a valid sessionid and returns the results of that session(0) if it still exists (unexpired maybe because of a huge expire time of Now()+7*24*60*60 you once may have set), and returns the results of a new session if it doesnt. I dont think you have shown us where you send the cookie back to the browser, i do it by setting $cookie in one of three places, then using print $q->header(-cookie=>$cookie); Note that two of those places set $cookie = $q->cookie(TSSID => $session->id ); (Note that uses the default cookie -expires. http://perldoc.perl.org/CGI.html#HTTP-COOKIES says "If an expiration date isn't specified, the cookie will remain active until the user quits the browser." so everytime they quit the browser there will be no more cookie sent when they start it up again.) For your login scheme to work you have be be setting the cookie somewhere and sending to back to the browser, but if you dont use $cookie = $q->cookie(CGISESSID => $session->id ); you may be sending the wrong cookie value back. In fact if you use $cookie = $q->cookie(CGISESSID => $sid ); and $sid is 0 you are in trouble, in fact reusing that 0 session. This goes to show how valuable use warnings; can be, even if it seems to break EVERYTHING at first.

      Hi

      First let me get htis out of the way:

      sub SetUserSessionCookie { my ($sname,$sid) = @_; #use CGI qw/:standard/; #use CGI::Cookie; my $sessioncookie = new CGI::Cookie(-name=>$sname,-value=>$sid,-ex +pires=>$session_cookie_timeout,-path=>'/cgi-bin',-domain=>$domain,-se +cure=>1); print header(-Cookie=>[$sessioncookie],-type=>"text/html"); }

      The cookie is set anew each time I log in.

      I will try to attach screen shot of firefox|options|cookies. Interestingly enough there is another unknown cookie that get posted to the page. Don't know where it comes from.Not in my code.

      I will rake your advice and try to gin up something that will work. I have been fooling around with this all afternoon and it is very tiring. I usually (with advice) get issues resolved much faster.

      Best regards

        Interestingly enough there is another unknown cookie that get posted to the page. Don't know where it comes from.Not in my code.
        Analytics software is often inserted at the server (e.g. Apache) level. My bet is that's the source.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        When you call SetUserSessionCookie what do you pass as $sname and $sid, if $sid is zero or $sname is not CGISESSID that may be where your problem is.

        Infact i forgot to suggest you check your mysql table for a sessionid of 0, and if you find it plain delete it. if you call $session  = new CGI::Session("driver:MySQL", $sid, {Handle=>$dbh, LockHandle=>$dbh}); when $sid is zero and there is no sessionid 0 you will get a new sessionid back

        my $dbh = ""; my $session = ''; my $sessionname = 'CGISESSID';

        is set at the beginning of the file and used all over including set and get cookies.

        I finally found where the expiration had been set at 1d and changed it to 7.

        The cookies are persistent. Checked before and after and against the sessions MySQL table.

        Best regards

      If OP is using CGI::Session then most of that stuff is extraneous
        Hi

        Well it appears I hve worked this out. I think the problem was th "mystery" cookie that had no name and blew the routine up. Still don't know where it comes from but appears each time I run.

        sub GetUserSessionCookie { warn("Entered GetUserSessionCookie Sessionname: '$sessionname'"); + my $sid; my $sessionname = 'CGISESSID'; # # fetch existing cookies my %cookies = CGI::Cookie->fetch; # warn Dumper \%cookies; while ( my ($sessName, $sessId) = each(%cookies) ) { # Dumper($sessId); if ($sessName eq $sessionname) { $sid = $sessId; } } # $sid = '12ba7ce0cfeeae8e8a934af6724910e9'; # $sid = '1492'; # $sid = 0; return $sid; }

        Whew. Thanks all.

Re: Cookie->fetch problem
by Anonymous Monk on Mar 09, 2017 at 23:51 UTC

    Hi,

    In the posted subroutine you have   use CGI qw/:standard/;

    But it doesn't make use of :standard or "CGI" at all -- its extraneous

      Forgot to tale it out. Not so easy. Now I can't log out. Ugh!! Cleared all the cookies and shut down. Still logged in Obviously the logged in flag is still st. Tomorrow another day.

        Hi: Round and round. Just can't recover a $sid from a cookie.

        Tried count on the cookies and it returned 0 Still struggling with this hole in my program. There are three cookies associated with my site.

        Fri Mar 10 12:31:32 2017 manage_users.cgi: keycount: '0' at /home/jalamior/www/httpsdocs/cgi-bin/lib/perl/manageusers.pm line 681.

        my %cookies = CGI::Cookie->fetch; my $count = keys %cookies; warn("keycount: '$count'"); while(my($key, $value) = each %cookies){ Dumper \$key; Dumper \$value; if($key eq $sessionname){ $sid = $value; } }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-04-18 23:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found