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

Please Note:

OS: Windows XP
Web Server: IIS
Perl: ActivePerl


I am finding it difficult to deal with cookie in Perl CGI. I have a webpage, say Login Page, where on the admin enters the credentials and after validating the credentials he/she is presented with subsequent webpages as he/she browses them. No webpage must be directly opened by entering its URL / Bookmark without providing the credentials.

Hence, I need to store the credentials and they need to be checked by each web page before their contents are displayed.

By following this perl doc: http://perldoc.perl.org/CGI/Cookie.html I have been able to store cookies and display them somehow but am not sure as to how to make them accessible to the Next Web Page that does not store/create them and just needs to use their values.

I used this:

$login_cookie = new CGI::Cookie(-name=>'loginID',-value=>'admin +'); $password_cookie = new CGI::Cookie(-name=>'loginPassword',-value=>' +go'); print header(-cookie=>[$login_cookie,$password_cookie]);

The last line causes the following output to be displayed:

Set-Cookie: loginID=admin; path=/ Set-Cookie: loginPassword=go; path=/ + Date: Thu, 03 Nov 2011 16:42:20 GMT Content-Type: text/html; charset +=ISO-8859-1

And these lines do not work:

%cookies = CGI::Cookie->fetch; for (keys %cookies) { print($cookies{$_}); }

Most likely, I am not able to understand as to how to handle cookie in Perl CGI. This is where I am finding myself very poor and am being forced to move to some other stuff such as PHP wherein handling Cookie is just like going to a candy shop. However, that is not what I want to. I want to know how to do these stuffs in Perl. And that's why I an here in this Monastery!

Replies are listed 'Best First'.
Re: Cookie and Session
by aaron_baugher (Curate) on Nov 03, 2011 at 18:05 UTC

    If your Set-Cookie: header is being displayed in the browser, then the browser isn't seeing it as a header. It looks like you're printing some HTML first, and then trying to send the header with cookies later, so it's being seen as part of the page text. Make sure you print the header first, before any other output.

Re: Cookie and Session
by chromatic (Archbishop) on Nov 03, 2011 at 17:28 UTC
    And these lines do not work:

    Please post a minimal (but complete) program which demonstrates the problem. 10-15 lines of code should be sufficient.


    Improve your skills with Modern Perl: the free book.

      Here is the first page that is called when the "Submit" button is clicked and "User ID and Password" is passed (via the POST method):

      use CGI qw/:standard/; use CGI::Cookie; print "<html><head>\n\r<title>Validating</title></head><body>"; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $request,$ENV{'CONTENT_LENGTH'}) or die "Could not get + query\n"; } @parameters = split(/&/,$request); foreach $p (@parameters){ $p =~ s/\+/ /g; ($para,$value) = split(/=/,$p); $para =~ s/%([0-9A-F][0-9A-F])/pack("c",hex($1))/ge; $value =~ s/%([0-9A-F][0-9A-F])/pack("c",hex($1))/ge; $PAIRS{$para} = $value; } if($PAIRS{"login_id"} eq("admin") && $PAIRS{"login_password"} eq("go") +){ $login_cookie = new CGI::Cookie(-name=>'loginID',-value=>'a +dmin'); $password_cookie = new CGI::Cookie(-name=>'loginPassword',-valu +e=>'go'); header(-cookie=>[$login_cookie,$password_cookie]); print "<script type='text/javascript'> <!-- window.location = 'work_with_cookies.pl'; //--> </script>"; } else{ print "<script type='text/javascript'> <!-- window.location = 'admin_login.html'; //--> </script>"; } print "</body></html>";

      And here is the Perl program that is called after creating the cookies:

      work_with_cookies.pl

      use CGI qw/:standard/; use CGI::Cookie; print ("<html><head>\n\r</head><body>"); %cookies = CGI::Cookie->fetch; print $cookies{"loginID"}; print $cookies{"loginPassword"}; print "<hr />"; print ("</body></html>");

      But I am getting nothing on the above page except the Horizontal Line. On the previous page if I use "print" before the "header" then I get the credentials as well as the other stuffs mixed with them as posted in the original post above.

      I repeat my question/problem: I am not able to set cookies and fetch/use them from/on the some other page that requires to validate the credentials before displaying its contents.

        print "<html><head>\n\r<title>Validating</title></head><body>";

        Cookies must go in the HTTP header. If you print HTML first, you've given up your chance to print any HTTP headers. Print the header with any cookies first.

        if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $request,$ENV{'CONTENT_LENGTH'}) or die "Could not get + query\n"; } @parameters = split(/&/,$request); foreach $p (@parameters){ $p =~ s/\+/ /g; ($para,$value) = split(/=/,$p); $para =~ s/%([0-9A-F][0-9A-F])/pack("c",hex($1))/ge; $value =~ s/%([0-9A-F][0-9A-F])/pack("c",hex($1))/ge; $PAIRS{$para} = $value; }

        Get rid of this code; it's buggy (I count at least three bugs and one denial of service attack) and you're already using CGI. Use its param() functions and save yourself the headache.


        Improve your skills with Modern Perl: the free book.