[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