[Catalyst-commits] r7223 - trunk/examples/CatalystAdvent/root/2007/pen

jasonk at dev.catalyst.perl.org jasonk at dev.catalyst.perl.org
Tue Dec 4 16:41:17 GMT 2007


Author: jasonk
Date: 2007-12-04 16:41:16 +0000 (Tue, 04 Dec 2007)
New Revision: 7223

Added:
   trunk/examples/CatalystAdvent/root/2007/pen/8.pod
Log:
Checking in a tutorial on inline authentication for the advent calendar, for
day 8, to go after jayks authentication tutorial scheduled for day 7.



Added: trunk/examples/CatalystAdvent/root/2007/pen/8.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/pen/8.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2007/pen/8.pod	2007-12-04 16:41:16 UTC (rev 7223)
@@ -0,0 +1,143 @@
+
+=head1 Inline Authentication Without Redirection
+
+Yesterday Jay Kuri covered Adding Authentication to your Catalyst App, which
+showed you how to determine if the user needed to authenticate, and if they
+did to redirect them to a login controller.  Today I'm going to show you
+an alternate approach, one that doesn't require redirection, that just
+handles the login inline.
+
+Why would you want to handle the login inline, rather than redirecting to a
+login page?  Have you ever had to login to a web application and fill out a
+lengthy form, only to find out when you go to submit that your session has
+timed out and you need to login again?  You end up having to do all kinds of
+contortions to use applications like this, things like opening up another
+window, logging in, and then going back to the original window to submit
+the form again.  This inline technique can overcome that, by allowing
+the login form to carry on your submitted form data along with it.
+
+=head2 Creating the auth controller
+
+When I use this method, I like to isolate all the authentication pieces
+into their own controller.  We'll start it out the same way any old
+controller starts out.
+
+    package MyApp::Controller::Auth;
+    use strict;
+    use warnings;
+    use base qw( Catalyst::Controller );
+
+Next we need an action that can check whether the user needs to be
+authenticated or not.
+
+    sub check_login : Private {
+        my ( $self, $c ) = @_;
+        
+        if ( $c->user_exists ) { return 1 }
+        
+        my $username = delete $c->request->params->{ '__username' };
+        my $password = delete $c->request->params->{ '__password' };
+        
+        if ( $username && $password ) {
+            if ( $c->login( $username, $password ) ) {
+                return 1;
+            }
+            $c->stash->{ 'error_msg' } = 'Incorrect username or password';
+        }
+        
+        $c->stash->{ 'template' } = 'auth/login.tt2';
+        $c->detach( 'View::TT' );
+    }
+
+You can also throw in a regular old login method, in case you need somewhere
+to link to when someone clicks a login button in the applications header or
+something like that.
+
+    sub login : Local {
+        my ( $self, $c ) = @_;
+        
+        $c->forward( 'check_login' );
+    }
+
+And for good measure, put a logout action in here too.
+
+    sub logout : Local {
+        my ( $self, $c ) = @_;
+        
+        $c->logout;
+        $c->response->redirect( $c->uri_for( '/' ) );
+    }
+
+=head2 The login template
+
+To go along with your controller, you need a login template, in
+root/auth/login.tt2.
+
+    <form method="post">
+        [% IF error_msg %]
+        <span class="error">[% error_msg %]</span>
+        [% END %]
+        
+        <label for="__username">Username:</label>
+        <input type="text" name="__username" size="40" />
+        <br />
+        
+        <label for="__password">Password:</label>
+        <input type="password" name="__password" size="40" />
+        <br />
+        
+        [% FOREACH p IN Catalyst.request.params.pairs %]
+            [% NEXT if p.key.matches( '^__' ) %]
+            <input type="hidden" name="[% p.key %]" value="[% p.value %]" />
+        [% END %]
+        
+        <input type="submit value="Login" />
+    </form>
+
+=head2 How to use it
+
+To use this, all you need to do is at any point where you want the user to
+login, forward them to the check_login action in your auth controller.  So
+for example, if you want to have B<every> page in your application protected,
+put this in your root controller.
+
+    sub auto : Private {
+        my ( $self, $c ) = @_;
+        
+        $c->forward( '/auth/check_login' );
+        return 1;
+    }
+
+=head2 How it works
+
+The way this works is by shortcutting the normal dispatch process if the
+user needs to authenticate.  If authentication is required, then the
+template gets set to the login form, and we add any form data as hidden
+fields to the login form, then detach to the template processor to render
+it.  When the form is submitted, it gets submitted to the URL the user
+originally requested, which means you don't have to keep track of what
+they were requesting in order to redirect them back to it after the
+login is complete.
+
+When they submit the form, the check_login method is going to see that the
+username and password fields were populated, and attempt to log them in with
+those credentials. It will also remove those entries from the
+C<< $c->request->params >> hash so they won't conflict with the real form
+parameters (this is also why they are named with two leading underscores,
+with the assumption that your real forms won't have fields with those names,
+if that assumption is incorrect then you may have to modify the field names
+used here.
+
+If the login is successful, then the dispatch process will continue as
+normal, passing the request data on to whatever action was supposed to
+get it in the first place.  If they login was not successful, the get
+the login form again.
+
+=head1 AUTHOR
+
+Jason Kohles, E<lt>email at jasonkohles.comE<gt>
+
+L<http://www.jasonkohles.com/>
+
+=cut
+


Property changes on: trunk/examples/CatalystAdvent/root/2007/pen/8.pod
___________________________________________________________________
Name: svn:keywords
   + Id Author Rev Date URL
Name: svn:eol-style
   + native




More information about the Catalyst-commits mailing list