Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Good way to redirect to a "members only" section of website

by yagna (Novice)
on Feb 02, 2013 at 15:24 UTC ( #1016720=perlquestion: print w/replies, xml ) Need Help??
yagna has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks, This is not a question regarding a particular perl code. I want some guidance regarding right approach. I am trying to build a website that is available for logged in users only. I have a script that does simple username password authentication. After the login script does validation I want the user to be logged into the main webpage. The functionality is almost identical to what Perlmonks login page does. Once successfull authentication, it logs the person into main.cgi. Does the login page do the authentication and then redirection upon successful authentication? Or does the login page call another cgi that does validation and upon unsuccessful authentication redirect to the login page? The application is a simple two page application: One login script and another landing page/script. The landing page will offer functionality via ajax calls. Let me know if I am unclear. Thanks, Yagna
  • Comment on Good way to redirect to a "members only" section of website

Replies are listed 'Best First'.
Re: Good way to redirect to a "members only" section of website
by ww (Archbishop) on Feb 02, 2013 at 16:29 UTC
    And "hi" back, Yagna. Welcome to the Monastery.

    But I'm confused. You say "I want the user to be logged into the main webpage."

    Do you mean "logged into the default page (perhaps index.html -- ie, in some vernaculars, what's called the "landing"page) for the visitor initially arriving at your site, or do you mean that a successful login puts the user on a page whereon s/he can interact with the "two page application?"

    My personal preference is to have the login script redirect to the ap if the uname/pw passes your tests... and, otherwise, to have it call a second CGI script which will throw up a new page which says 'That username doesn't match that password" or similar and provides a link (emphasis, LINK; NOT a redirect>) to the default (index.html or whatever).

    I'm not going to bother to offer a detailed (and perhaps even rational) explanation of that preference; it's not something I've detailed -- in my own mind; let alone on paper -- to the degree needed to make it readable and defensible (which it may or may not be)   :( .

      Yagna, my best advice is to use Catalyst to get this functionality nicely.

      You include Catalyst::Plugin::Authentication just like it says in the Catalyst Tutorial.

      You basically end up leading off each templated page that you want restricted to logged-in users with this:

      [% IF c.user_exists %] ...the rest of your content here... [% END %]
      Your home page or whatever you want to call it won't include this code at the head, so users who haven't logged in yet can see the content that you've not restricted. It works nicely without a lot of fuss. Have fun!

        Hi Shuraski, Since my application is simple I wanted to stay away from frameworks. I will test it out just get a feel for using catalyst. Thanks, Yagna
      Hi WW, The default page is as you mentioned index.cgi. Sounds like the general approach is to redirect to a index.html/index.cgi on successful login. Just a clarification: the two page includes the login page (so I have the login page and an index.cgi) Thanks for confirming! Yagna

        " the two page includes the login page...."
        Actually, if I read your explanation as you intended, that's exactly what I'm urging you to avoid.

        My preferred schema is:
        1. Create a default, static "index.html (.asp. .net, whatever)" FOR EVERY VISITOR which includes a link to "login.cgi"
        2. Have login.cgi's (separate) action script (call it "login_test.cgi") check the uname and pw against whatever you're using for your "approved members" list
            ...if successful,
          call "application_page1.cgi"
            } else {
   "page2.html" which announces "login failed" or similar (as in my initial reply) and provides a link to the default ("index.html" or whatever).

        You can, without dangerously deviatating from my schema, have login_test.cgi's failure action send a user who entered the wrong credentials directly back to index.html without any explanation, but that's unkind to the maker of an innocent error.

        Please excuse my assumptions about your intent; I've been known to err (but with good intent) in that area.

Re: Good way to redirect to a "members only" section of website
by ww (Archbishop) on Feb 02, 2013 at 19:33 UTC

    ... and the layout here ain't exactly wonderful but, anyway, here's a snippet from an "index.html" (default) page:

    <form action="../cgi-bin/login.cgi" name="checkin" id="checkin" method +="post"> <label for="ckin">Account ID: &nbsp; <input type="text" id="ckin" name="ckin" size="15"> </label> &nbsp; <input name="Submit" type="submit" value="Ordering"> </form>

    The 'action' element of the form specifies the file to be used for checking the input, <Aside: which, in this case, is solely an account ID (all alphas) because the site owner estimates his risks are minimal (for reasons beyond the scope of this discussion) despite using a single-element login). /Aside>

    The called script ("login.cgi") is an antique, but works more or less like this:
    #!/usr/bin/perl -wT # read about Tainted input or die use strict; use CGI qw(:standard escapeHTML); use vars qw ( @accts $acct_name $all_accts ); our $value = (param('ckin')); # get account ID from the form above unless ( $value =~ /^[a-z]{5}$/i ) { &out_badlog(); # See *1 exit; } # See *2 open (INFILE,'<', 'accts.db') or die "Can't open accounts data"; our ( @accts ) = split /\s/,<INFILE>; close (INFILE); for $acct_name( @accts ) { $all_accts = $all_accts . $acct_name; } if ( $all_accts =~ /$value/ ) { &out_logged_in($value); # See *3 } else { &out_badlog($value); } ... # BAD LOGIN PAGE - output a doc sub out_badlog { print <<_END_OF_INPUT_ <html lang="en"> <head> <title>Sample title</title> <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> <meta name="description" content="..."> <meta name="keywords" content="..."> <meta http-equiv="Content-Style-Type" content="text/css"> <link rel="stylesheet" type="text/css" href="../foo.css"> </head> <body> ... banner, other foofarawh here.... <h1 style="margin-left: 3em;">Bad login!</h1> _END_OF_INPUT_ ; print ('<h2 style="margin-left: 4em;">Login attempted was: ' . $value +. '</h2>'); print <<_END_OF_VAL <h3 style="margin-left: 8em;">That was NOT a valid login!</h3> <p> &nbsp; </p> <p style="margin-left: 16em;"><a href="../index.html">Back to login pa +ge</a></p> <br> </body> </html> _END_OF_VAL ; }

    ...and, similarly for the good log-in sub...

    Hope this helps... (and does not suggest too many obsolete or bad practices)

    *1 This sub could redirect to page2.html or could (using a heredoc, for instance) produce the hmtl for page2.htm and feed it to the user's browser.

    *2 'accts.db' holds a single (long!) string of all valid accounts.

    *3 The sub 'out_logged_in()' produces renderable .html -- which, for ex., could be the source of your "application_page1.cgi" -- but which, in this case, uses a heredoc to create a page allowing the successfully-logged-in-user to continue to a variety of applications pages.

    You can do this a good many different ways and careful scrutiny will tell you it's not exactly in accord with my currently preferred schema, but it is, I think, easily enough understood and adapted. You'll find better ways as you grow in your Perl-fu.

    Update: Edited out an irrelevant <style=...> to further reduce the width of the code and fixed the closing "Aside" pseudotag. IOW, no substantive change.

      Hi ww, Thanks for the code snippet. This works for me. Thanks again! Yagna

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1016720]
Approved by moritz
[shmem]: Discipulus reminds me of an irish saying: "I would guess a tomorrow can wait 'til this day is done" :-)
[LanX]: nite! :)
[Discipulus]: or a spanish one: ' qui mucho se despide no quiere despedirse'
shmem slides into the envelope
[shmem]: Discipulus *quien*
[Discipulus]: quien ..
[Discipulus]: me too, i need a Dumas time, see you
[shmem]: que descanses bien, aprendiz

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2017-04-29 22:53 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (534 votes). Check out past polls.