in reply to Cookie->fetch problem

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.

Replies are listed 'Best First'.
Re^2: Cookie->fetch problem
by Anonymous Monk on Mar 10, 2017 at 00:01 UTC
    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.

        I bet it was just the my $sessionname = 'CGISESSID';

        When i run

        my %cookies = CGI::Cookie->fetch; print encode_entities(Dumper(\%cookies))."\n";
        I see
        $VAR1 = { 'TSSID' => bless( { 'name' => 'TSSID', 'path' => '/', 'value' => [ '40d64ab47d37f6c7ae806dc11a +59f242' ] }, 'CGI::Cookie' ) };
        Remember im using TSSID rather than CGISESSID. So you are setting $sid to a hash reference that looks a whole lot like what i get when i run
        my $cookie2 = $q->cookie(TSSID => $session->id ); print encode_entities(Dumper($cookie2))."\n";
        ie:
        $VAR1 = bless( { 'name' => 'TSSID', 'path' => '/', 'value' => [ '40d64ab47d37f6c7ae806dc11a59f242' ] }, 'CGI::Cookie' );
        and that as $sid makes no sense if you ran
        my $sessioncookie = new CGI::Cookie(-name=>$sname,-value=>$sid,-expire +s=>$session_cookie_timeout,-path=>'/cgi-bin',-domain=>$domain,-secure +=>1); print header(-Cookie=>[$sessioncookie],-type=>"text/html");
        but does make sense if you instead ran
        print header(-Cookie=>[$sid],-type=>"text/html");
        see if i run
        { my $sname = 'CGISESSID'; my $cookie2 = $q->cookie(TSSID => $session->id ); my $sessioncookie = new CGI::Cookie(-name=>$sname,-value=>$cookie2,-pa +th=>'/cgi-bin'-secure=>1); print encode_entities(Dumper($sessioncookie))."\n"; }
        i get
        $VAR1 = bless( { 'name' => 'CGISESSID', 'path' => '/', 'value' => [ bless( { 'name' => 'TSSID', 'path' => '/', 'value' => [ '40d64ab47d37f6c7a +e806dc11a59f242' ] }, 'CGI::Cookie' ) ] }, 'CGI::Cookie' );
        and that just looks wrong.

        and note that if i run

        my $sname=''; my $cookie3 = new CGI::Cookie(-name=>$sname,-value=>$session->id,-pa +th=>'/cgi-bin',-secure=>1); print encode_entities(Dumper($cookie3))."\n";
        i get back
        $VAR1 = bless( { 'name' => '', 'path' => '/cgi-bin', 'secure' => 1, 'value' => [ '40d64ab47d37f6c7ae806dc11a59f242' ] }, 'CGI::Cookie' );
        ie: a cookie with no name

Re^2: Cookie->fetch problem
by tultalk (Monk) on Mar 09, 2017 at 22:33 UTC
    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

        Hi:

        It is setting the cookie with the session name as CGISESSID name and and the unique SID such as 08b6bf0fc7723abbc134fb0f1a09c5e8he SID generated with an MD5 hash using the username and password. This is done in the login iframe form and that hash is sent back to the server for verification. That sid is stored in the sessions table

        Hi

        When the the page with the iframe is sent to the client, the call to get the cookies returns 0 if no cookies. That causes creation of a new session and the MD5 data being sent with the iframe response so a SID of 0 is just a flag. The call to set the cookie is:

        #Set session cookie on client SetUserSessionCookie('CGISESSID', $sid);

        The SID being the MD5 hash of the username and password.

      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

        another thing is that you may want to check your mysql sessions table to find any session-rows that have _SESSION_ETIME > 604800 that would have been set as the result of that Now()+7*24*60*60 call. You may want to plain delete them and force those users to login again or reset them to 604800 ( 7 days)