Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

CGI::Application redirecting from one handler to another.

by skx (Parson)
on Jan 02, 2004 at 17:04 UTC ( [id://318353]=perlquestion: print w/replies, xml ) Need Help??

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

I've just fallen in love with CGI::Application after diving into it for the first time.

However I have one small problem concerning redirecting from one handler to another.

I have an application where users may signup to have an account on the system, using CGI::Session to maintain the logged in state - and a table of usernames and passwords in a database.

The way that I initialy handled this was to have a pair of handlers "join" which presented the signup page (via HTML::Template) and "create" which would be invoked as the result of the "join" page's form submissoin.

This worked OK, but didn't give me a clean place to handle errors.

So now I have a more complex system.

The "join" method will present a signup form for the user to enter their username and password etc. The target of the form will be the join page itself - this allows me to catch errors early and output the form again with any errors such as "the two passwords you've given do not match", "username already used", etc.

If the validation passes then I'd like to redirect to another handler - the create one - to actually create the account.

I've successfully used code like this to jump from one handler to another:

my $redirect_url=$this_url.'?node=viewprofile;username='.$user; $self->header_type('redirect'); $self->header_props(-url => $redirect_url); return;

For the signup this works well if I can tag on the extra details such as email and username - but it has the problem that the password is exposed.

Now I have two solutions:

  • I make the redirect use a POST instead of a GET.
  • I MD5 the password in the redirected URL - which is fine as I intend it to be hashed in the database anyway.

What should I be doing - right now I'm thinking that POSTing AND hashing is the correct thing to do, but I can't seem to get that to work.

How do I make one CGI::Application handler redirect to another via a POST method?

Steve
---
steve.org.uk

Replies are listed 'Best First'.
Re: CGI::Application redirecting from one handler to another.
by jeffa (Bishop) on Jan 02, 2004 at 17:22 UTC
    I feel that this task is one that should not be seperated into two "handlers". You can always take care of abstraction by writing two "utility" methods/functions that verify and create respectively, but the task of "logging in" is better handled in one handler, IMHO.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      This code is related to the creation of accounts rather than logging in - obviously a user cannot login until their account has been created!

      Still I think that perhaps you're correct and that instead of having two handlers I should just keep one long one. It just seemed right to make it a two step affair as conceptually it is.

      I guess that's just an implementation detail though and it would solve my problems.

      Steve
      ---
      steve.org.uk
Re: CGI::Application redirecting from one handler to another.
by Chmrr (Vicar) on Jan 02, 2004 at 18:16 UTC

    Having just solved a very similar problem, I would suggest the following pseudocode. What it boils down to is using the query object to pass parameters to the other runmodes.

    sub join { # This is the 'join' runmode my $self = shift; my $q = $self->query; # It submits to the verify runmode if ($self->query->param('error')) { # We just tried to submit, but had error(s); print them } # Print the rest of the form, etc } sub verify { # 'verify' runmode my $self = shift; my $q = $self->query; # Do error checking unless (@errors) { # This is how we 'redirect' without redirecting. $q->param('username',$username); $q->param('password',$password); return $self->create; } else { $q->param(-name => 'error', -value => \@errors); return $self->join; } } sub create { # 'create' runmode my $self = shift; my $q = $self->query; # Create the account return $self->viewprofile; } sub viewprofile { # 'viewprofile' runmode # ..uses $q->param('username') which is either supplised by the user +, or # by the code in 'verify', which was passed to 'create' and then on # to us. }
Re: CGI::Application redirecting from one handler to another.
by Aristotle (Chancellor) on Jan 02, 2004 at 17:57 UTC
    It seems like this would be easier the other way around: validate the data in the create handler and if there's an error, redirect back to the join page.

    Makeshifts last the longest.

Re: CGI::Application redirecting from one handler to another.
by valdez (Monsignor) on Jan 02, 2004 at 17:41 UTC

    Few comments on your idea: the "create" run mode (or handler) could be invoked directly, is it safe? if you already have a session, why don't you place all sensible data in the session? building URLs by hand may cause some serious problems, try instead with URI->query_form.

    Ciao, Valerio

      The problem here is that the sessions are only really used when the user logs in - so they don't apply in a useful way at the point the account is created.

      Building URLs by hand is annoying, though I can use the ->param() function to make sure I've got everything I need.

      Steve
      ---
      steve.org.uk
Re: CGI::Application redirecting from one handler to another.
by talexb (Chancellor) on Jan 02, 2004 at 17:15 UTC

    Sure, do an MD5 of the password -- you never want to have the password going anywhere in plaintext. If the password passes your 'tough enough' rules, MD5 it, re-direct to the place where you add the new user and password to the database, and continue.

    Later, you should be able to log in using the same MD5 operation on the same password.

    Am I missing something obvious?

    Alex / talexb / Toronto

    Life is short: get busy!

      The problem is that even if the password is hashed the redirect will lead to an URL that is visible to the user.

      Which means that they could cheat and bookmark this in the future to create arbitary unvalidated accounts - now at the moment I have a simple scheme to avoid this with the use of sessions, but making this less visible would be a good thing.

      Steve
      ---
      steve.org.uk

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (1)
As of 2024-04-25 01:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found