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

I have spent two days on this and cannot figure what is the problem with CGI!

I grab a username and password from one perl script and passit to another...It is in this next script that I generate a cookie. However, the cookie is not registered by the browser unless I issue the following lines:

print "Set-Cookie: $cookie1\n"; print "Content-Type: text/html\n\n";

However, I do not want to print the cookie to the screen! Please help, I have included the methods I have created and if you could let me know where Iam wrong please.

sub SetCookie { use CGI qw/:standard/; use CGI::Cookie; $cookie1 = new CGI::Cookie(-name=>'DB', -value=>{ username => $DBuser, password => $DBpasswd, }, -expires => '+1H'); print "Set-Cookie: $cookie1\n"; print "Content-Type: text/html\n\n"; } sub ReadCookie { %cookies = fetch CGI::Cookie; @id = $cookies{'DB'}->value; $exp = $cgi->header( -cookie => DB); print "$id[0] = $id[1]; $id[2] = $id[3]; Expiration = $exp"; }
Thanks, Siumon

Replies are listed 'Best First'.
Re: CGI::Cookie issues
by jarich (Curate) on Nov 21, 2002 at 05:33 UTC
    I suspect that you're having difficulty understanding how CGI works. Anything you want the server to send to the browser has to be printed to STDOUT. In the case of cookies these must be included in the headers that are printed before any html output is sent. Which is why grep suggested:
    print $query->header(-cookie=>$cookie);
    I hope the follow example works for you and helps you understand cookies better: Of course I'm not using CGI::Cookie here, but it should illustrate the point regardless. If you want to try this script out you can visit http://perltraining.com.au/~jarich/cgi-bin/cookietest.cgi.

    Not having used CGI::Cookie before I don't think I can comment much on it. I can mention that some of your problems may be in the use of "H" instead of "h" in your expiry date. I know that this caused me some problems presumably because the browser expired my cookie very quickly...

    The following functions:

    #!/usr/bin/perl -wT use CGI; use CGI::Cookie; use Data::Dumper; use strict; my $cgi = new CGI; setcookie("fish", "fosh"); getcookie(); sub setcookie { my ($DBuser, $DBpasswd) = @_; my $cookie1 = new CGI::Cookie(-name=>'DB', -value=>{ username => $DBuser, password => $DBpasswd, }, -expires => '+1h'); print $cgi->header(-cookie=>[$cookie1]); } sub getcookie { my %cookies1 = fetch CGI::Cookie; return unless %cookies1; my $db = $cookies1{'DB'}; return unless $db; my %dbvs = $db->value if $db; print Dumper(%dbvs); print Dumper(%cookies1); }
    work great for me.

    Hope it helps.

    jarich

    Update: Had a revelation about H vs h and finally made the functions work consistently.
    Update2: It occurs to me that you may feel that printing the cookie to the screen is a security risk because passwords may be involved. Whilst this is true I hope you realise that any passwords you store in the cookie will be visible to the owner of the cookie (if they want to see them) as well as to anyone who can see the environment variables of the browser process. What is more the cookie will be passed to all other websites in your domain. So, for example, if I pass out a cookie to the www.unimelb.edu.au domain, then it's not just my cgi scripts that can access that cookie, but every website over the whole campus. (Extrapolate for something like geocities...) As a general rule, storing passwords in a cookie is a really bad idea. Storing anything that you don't want the user to be able to read and record is just asking for trouble.

Re: CGI::Cookie issues
by grep (Monsignor) on Nov 21, 2002 at 03:25 UTC
    You can use the header method from CGI.

    from the CGI docs
    print $query->header(-cookie=>$cookie);

    This will not prevent it from printing to the screen when run as a command line program - since CGI uses STDOUT for it's content. You could disable from the command line by checking the $query->request_method() a command line invocation should IIRC not return anything



    grep
    Mynd you, mønk bites Kan be pretti nasti...

      Thanks... That hides the header... which is good! However, I still cannot get the ReadCookie() method to read the cookie... or more correctly, I cannot get the cookie set properly.

      #!/usr/local/bin/perl use CGI qw/:standard/; use CGI::Cookie; $passwd="toronto5"; $cookie1 = new CGI::Cookie(-name=>'DB', -value=>{ username => simony, password => toronto5, }, -expires => '+8H'); #print header(-cookie=>[$cookie1]); print "Set-Cookie: $cookie1\n"; print "Content-Type: text/html\n\n"; print $cookie1;

      The above has no problem setting the cookie if it stands alone. I don't want to be a code mooch, but finding documentation that is correct is not easy--even the man pages are not consistant. Can you provide any direction in this manner?

      Thanks, Simon