Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

[SOLVED] possible to repeat if statement?

by jaffinito34 (Acolyte)
on May 04, 2013 at 15:23 UTC ( #1032051=perlquestion: print w/replies, xml ) Need Help??
jaffinito34 has asked for the wisdom of the Perl Monks concerning the following question:

I am running a login script and perhaps there is a better way to do this but I think I have it right. Here's how the program should run

fetch cookies check if authorized if yes, redirect if no, check for params if param check for credentials if credentials are good set authorized cookie redirect to default page else authorization failed display form to login

I feel this should work but I need to rerun the 'if param' if statement with the newly entered credentials to get this to work. Here is my code if its easier to look at that.

use DBI; use CGI qw /:standard/; use CGI::Cookie; use warnings; my %cookies = CGI::Cookie->fetch; if (defined $cookies{'authorized'}){ #redirect to search.cgi print redirect("search.cgi"); } if (param){ my $username = param('username'); my $password = param('password'); my $dbh = DBI->connect("dbi:SQLite:dbname=/var/tmp/database.db +","",""); my $sth = $dbh->prepare("select * from users where username = ? and password = ?"); $sth->execute($username, $password); my @row = $sth->fetch_array; if (@row){ #login successful # set 'authorized' cookie my $cookie = CGI::Cookie->new( -name=>'authorized', -value=>1, -path=>'/~default/chinook'); #-expires=>'+10m'); #redirect to search.cgi print redirect(-uri=>'search.cgi', -cookie=>$cookie); }else{ # login failed } } print header, start_html('Login'),h1('Login'), start_form, "Username: ",textfield('username'),br, "Password: ",password_field('password'),br, submit('Enter'), end_form, "\n";

Any ideas how to rerun the if(param) statement?

Maybe a subroutine?

Got it running, thanks to anyone who helped. Working code follows.

use DBI; use CGI qw /:standard/; use CGI::Cookie; use warnings; #print header('text/plain'); my %cookies = CGI::Cookie->fetch; if (! defined $cookies{'authorized'}) { if (param) { my $username = param('username'); my $password = param('password'); my $dbh = DBI->connect("dbi:SQLite:dbname=/path/to/dat +abase.db","",""); my $sth = $dbh->prepare("select * from users where username = ? and password = ?" +); $sth->execute($username,$password); my @row = $sth->fetchrow_array; if (@row) { #login successful, set authorized cookie my $cookie = CGI::Cookie->new( -name=>'authorized', -value=>1, -path=>'/default/path'); #-expires=>'+10m'); print redirect(-uri=>'search.cgi',-cookie=>$co +okie); } else { &print_login; exit; } } else { &print_login; exit; } } print redirect('search.cgi'); exit; sub print_login { print header, start_html('Login'),h1('Login'), start_form, "Username: ",textfield('username'),br, "Password: ",password_field('password'),br, submit('Enter'), end_form, end_html; exit; }

Replies are listed 'Best First'.
Re: possible to repeat if statement?
by davido (Archbishop) on May 04, 2013 at 16:26 UTC

    It's been years since I last did bare CGI, so with that in mind here goes... Invert the logic a little, and use a loop that blocks further progress until the user authenticates. Pseudo-code follows:

    while( ! defined $cookies{'authorized'} ) { if( param ) { if( validates ) { # Set authorization cookie next; # Auth check will pass, so this is # equiv to "last" } } # If we get here, the user hasn't successfully validated # Generate auth form. } # To arrive here we must have authenticated: Redirect.

    If you have creative control on this project, it seems that you're early enough along in the process that you could just ditch and run straight to Mojolicious::Lite, which will run in a CGI environment, but will greatly promote de-spaghettification of your code, and makes auth checks almost free.


      Genius thanks a lot

        puts you in an infinite loop of generating login forms.

Re: possible to repeat if statement?
by NetWallah (Abbot) on May 04, 2013 at 16:31 UTC
    What you have implemented can be categorized as a "state machine", or "workflow".

    More formal implementations of this are "data-driven", which means that each STATE and CONDITION combination drives you to either a new STATE or ACTION.
    All this is defined in a single data-structure (or "rule" type file).

    If you can restructure your program around this idea, it will become more stable, and extensible.
    However- you pay the up-front cost in engine implementation, and having to consider every STATE/CONDITION combination.
    There are several modules that can help - I don't have sufficient experience with them to advise. Search on the keywords "state machine", or "workflow".

                 "I'm fairly sure if they took porn off the Internet, there'd only be one website left, and it'd be called 'Bring Back the Porn!'"
            -- Dr. Cox, Scrubs

Re: possible to repeat if statement?
by sundialsvc4 (Abbot) on May 04, 2013 at 16:22 UTC

    Remember that, immediately after print redirect("search.cgi"); , you must return.   Your code should not proceed beyond that point, because having issued the redirect-order in response to this HTML packet, you have nothing further to do with this.   (The user’s browser will receive the redirect, and will act upon it, and so, at some time in the future, you’ll (maybe...) get another HTML packet from the same user requesting the new address.)

    The same thing is true, later on, when you (ask the browser to) redirect and (ask the browser to) set a cookie.   When you have given the browser that instruction, you are done (for now).   So, you must return.

    It is reasonable to generate the login form as your output, as you do now, either when “login failed” or,in the case where param is not-present, they are here for the first time and not-yet logged in.

    So, your (corrected) logic will have three possible outcomes, and it will execute one of these three and then return:

    1. If the user is logged-in, he is redirected to search.cgi.
    2. If the user presents valid credentials, he is redirected and a cookie is stored.
    3. Otherwise, the login form is displayed, with-or-without an “incorrect password” warning.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1032051]
Approved by Old_Gray_Bear
[afoken]: and tail is part of POSIX, less isn't.
[afoken]: So tail works at every Unix's prompt, less only on a subset.

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2017-01-17 20:14 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (158 votes). Check out past polls.