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

Ok, I am at the library and I just got done reading the third book on 'cookies'. They all tell you that you need to send cookies with the headers, right? Then how in the bloody world are you supposed to have a form ask for information THEN based on that information create cookies? None of the books even go into that topic, they just pretend the browser already has cookies and all you're trying to do is read them.

Can someone show me how to do something like:

1) Check if cookie exists and is valid 2) If it doesn't exist or if it's incorrect, print html form 3) From HTML form set a cookie when they click submit
If a cookie exists { if {#check for validity } else { #exit} } else { # since no cookie or no valid cookie was found, print HTML form asking + for input # # now that we have information, make a cookie, set it and refresh the +page }
Thanks everyone, I don't see why this topic isn't found in any of the books or docs I've read.

Replies are listed 'Best First'.
Re: How do they expect cookies to work (like this)??
by jasonk (Parson) on Sep 30, 2003 at 17:30 UTC

    After the form is submitted I assume you are showing the browser some kind of success page, correct? You would set the cookies in the headers of _that_ page.


    We're not surrounded, we're in a target-rich environment!
      No. That still doesn't help me SET a cookie after the headers. You just can't call a cookie without setting one and you can't set one after the headers, so how in the world am I supposed to accomplish that? This form has the action ''; meaning it doesn't bring you to a different page, instead it just reloads the one with the form. But with my if/else statements there should be a way to make it all work.

      Can someone show me an example on how to setup a snippet like this?

        Sure, I'll bite:

        #!/usr/bin/perl -w use strict; use CGI qw(header cookie); if (cookie("val")) { print header(),"Your cookie is still set"; } elsif (param("val")) { print header(-cookie=>cookie( -name =>'val', -value=>param("val"), -expires=>'+1M')),"Success! Your cookie should be set"; } else { print header(),q(<html><body><form method="POST" action=""><input ty +pe="text" name="val"><input type="submit" value="Click here"></form>< +/body></html>); }

        Steps: check for the cookie. If present, display still set page. If not, check for a parameter. If present, set the cookie and display success page. If not, display form. I haven't tested the above code, but you should be able to understand what the process entails. I used CGI for all the nasty work. Please click that link and read EVERYTHING. Then check out Ovid's CGI Programming with Perl course.

        Hope this helps.

        antirice    
        The first rule of Perl club is - use Perl
        The
        ith rule of Perl club is - follow rule i - 1 for i > 1

        Which part is confusing you? You have to wait to send the headers until after you add the cookie to them. Look at this example from the CGI.pm documentation.

        I believe you're confusing the idea of the script with the concept of page as it applies to the web browser.

        The script generates a page with the form, the form is submitted by the user back to the script which handles the submitted params and generates a page with either success or failure. It is in that "page"'s headers that you set your cookie.

        You basically had the logic right AFAICT in your original post's pseudo-code.

        [Jon]

Re: How do they expect cookies to work (like this)??
by cLive ;-) (Prior) on Oct 01, 2003 at 04:47 UTC
    I think what you're saying is that you want to be able to access the cookie you are about to set in the current invocation???

    If so, you need to set up a var to track this "cookie" (it's not a cookie before it's set, hence the quotes).

    #!/usr/bin/perl use strict; use warnings; use CGI; my $q = CGI->new(); our $cookie = ''; if ( defined $q->cookie('cookiename') ) { $cookie = $q->cookie('cookiename') # validate cookie here based on whatever } elsif ($q->param('some_field_name') { # form submitted $cookie = 'whatever'; } else { # show the html form }
    Then, whenever you print a page, ensure the cookie gets sent in the header.

    I think understanding exactly what it is you don't understand is more the problem here than the actual problemn. perhaps you can explain it in a bit more detail?

    .02

    cLive ;-)

    ps - you might want to look at the concept of using a "cookie jar" in your script. That way you can seamlessly ensure cookies get sent when you print headers. Here's a snippet....

    # at beginning of script use CGI; our @cookie_jar = (); our $q = CGI->new(); # when you want to set a cookie push @cookies, $q->cookie(-name=>'sessionID', -value=>'xyzzy', -expires=>'+1h'); # when you print a page, instead of calling $q->header # use this instead print cookie_header; # which sends all cookies sub cookie_header { return $q->header(-cookie=>\@cookie_jar); } # if you're on mod_perl, you also need to empty # the cookie jar here, so amend sub cookie_header { my header = $q->header(-cookie=>\@cookie_jar); @cookie_jar = (); return $header; }
    But, like I said, I'm grasping at straws here. I think if you could explain what you don't understand though, you'd probably find the answer yourself :)

    The key to successful programming is to understand the questions. Once you've done that, the answers are trivial :)

    .02

    cLive ;-)

      Ok, I will try to re-ask my question so you can better understand what I am aiming for.

      I want an HTML form (which asks for a username and password) to redirect back to itself and with the user/pass make a cookie. When the cookie is sent to header after it's detected, it will access semi-secure information and won't print the form anymore.

      In short, I want the form to make the cookies when it returns to itself after the user information is supplied.

      I have printed your snippets out and will be looking them over more extensively after work today but there are a few things I can honestly say I haven't seen before. For example the use of our.

      Thanks for your help.

        #!/usr/bin/perl use strict; use warnings; use CGI; our $q = CGI->new(); our @cookie_jar=(); our $secure_cookie = defined $q->cookie('securecookie') ? $q->cookie('securecookie') : ''; # is a valid cookie set? if ($secure_cookie) { if ( cookie_ok($secure_cookie) ) { show_secure_stuff(); } else { # invalid cookie, so delete and show form push @cookie_jar, $q->cookie( securecookie => '' ) show_form(); } } # have they just completed the form elsif ($q->param('username')) { check_login_combo(); } # first run, so show form else { show_form(); } sub show_form { # display login form here # with fields 'username' and 'password' } sub check_login_combo { # based on username, grab correct crypted password # from db/textfile and store in $stored_cryptpass # do various other error checks and re-present form # if invalid input my $user = $q->param('username'); my $pass = $q->param('password'); if ($stored_cryptpass eq crypt($pass,$stored_cryptpass) { push @cookie_jar, $q->cookie({-name=>'secure_cookie', -value=>"$user:$stored_cryptpass"}); show_secure_stuff(); } else { # bad login show_form(); } } sub cookie_ok { # do similar check on cookie my ($user,$cryptpass) = split ':', $_[0]; # grab stored_cryptpass and check return $cryptpass eq $stored_cryptpass ? 1 : 0; } sub show_secure_stuff { # display secure page here - ensuring you send the cookie print $q->header(-cookie => \@cookie_jar). 'rest of page here'; }

        .02

        cLive ;-)