Switch from 'sub base :Path :Args(0)' to 'sub index : Private' for
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Tutorial / Authentication.pod
index 438bdbd..d5401f8 100644 (file)
@@ -3,7 +3,6 @@
 Catalyst::Manual::Tutorial::Authentication - Catalyst Tutorial - Part 4: Authentication
 
 
-
 =head1 OVERVIEW
 
 This is B<Part 4 of 9> for the Catalyst tutorial.
@@ -46,16 +45,16 @@ L<AdvancedCRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
 
 =item 9
 
-L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
+L<Appendices|Catalyst::Manual::Tutorial::Appendicies>
 
 =back
 
 
-
 =head1 DESCRIPTION
 
 Now that we finally have a simple yet functional application, we can
-focus on providing authentication (with authorization coming in Part 5).
+focus on providing authentication (with authorization coming next in
+Part 5).
 
 This part of the tutorial is divided into two main sections: 1) basic,
 cleartext authentication and 2) hash-based authentication.
@@ -68,16 +67,16 @@ following command:
     IMPORTANT: Does not work yet.  Will be completed for final version.
 
 
-
 =head1 BASIC AUTHENTICATION
 
-This section explores how add authentication logic to a Catalyst application.
+This section explores how to add authentication logic to a Catalyst
+application.
 
 
 =head2 Add Users and Roles to the Database
 
-First, we add both user and role information to the database (we add the
-role information here although it will not be used until the
+First, we add both user and role information to the database (we will
+add the role information here although it will not be used until the
 authorization section, Part 5).  Create a new SQL script file by opening
 C<myapp02.sql> in your editor and insert:
 
@@ -120,10 +119,10 @@ Then load this into the C<myapp.db> database with the following command:
     $ sqlite3 myapp.db < myapp02.sql
 
 
-=head2 Add User and Role Information to Dbic Schema
+=head2 Add User and Role Information to DBIC Schema
 
 This step adds DBIC-based classes for the user-related database tables
-(the role information will not be used until the Part 5):
+(the role information will not be used until Part 5):
 
 Edit C<lib/MyAppDB.pm> and update the contents to match (only the
 C<MyAppDB =E<gt> [qw/Book BookAuthor Author User UserRole Role/]> line
@@ -334,16 +333,14 @@ Again, notice that your "result source" classes have been "re-loaded" by Catalys
 
 =head2 Include Authentication and Session Plugins
 
-Edit C<lib/MyApp.pm> and update it as follows (everything below C<DefaultEnd> is new):
+Edit C<lib/MyApp.pm> and update it as follows (everything below C<StackTrace> is new):
 
     use Catalyst qw/
             -Debug
             ConfigLoader
             Static::Simple
             
-            Dumper
             StackTrace
-            DefaultEnd
             
             Authentication
             Authentication::Store::DBIC
@@ -357,8 +354,8 @@ Edit C<lib/MyApp.pm> and update it as follows (everything below C<DefaultEnd> is
 The three C<Authentication> plugins work together to support
 Authentication while the C<Session> plugins are required to maintain
 state across multiple HTTP requests.  Note that there are several
-options for L<Session::Store|Catalyst::Plugin::Session::Store> (although
-L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap>
+options for L<Session::Store|Catalyst::Plugin::Session::Store> 
+(L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap>
 is generally a good choice if you are on Unix; try
 L<Cache::FileCache|Catalyst::Plugin::Cache::FileCache> if you are on
 Win32) -- consult L<Session::Store|Catalyst::Plugin::Session::Store> and
@@ -370,10 +367,12 @@ its subclasses for additional information.
 Although C<__PACKAGE__-E<gt>config(name =E<gt> 'value');> is still
 supported, newer Catalyst applications tend to place all configuration
 information in C<myapp.yml> and automatically load this information into
-C<MyApp-E<gt>config> using the
-L<ConfigLoader|Catalyst::Plugin::ConfigLoader> plugin.
-
-Edit the C<myapp.yml> YAML and update it to match:
+C<MyApp-E<gt>config> using the 
+L<ConfigLoader|Catalyst::Plugin::ConfigLoader> plugin.  Here, we need
+to load several parameters that tell 
+L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
+where to locate information in your database.  To do this, edit the 
+C<myapp.yml> YAML and update it to match:
 
     ---
     name: MyApp
@@ -386,7 +385,7 @@ Edit the C<myapp.yml> YAML and update it to match:
             # This is the model object created by Catalyst::Model::DBIC from your
             # schema (you created 'MyAppDB::User' but as the Catalyst startup
             # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::User').
-            # NOTE: Omit 'MyAppDB::Model' to avoid a component lookup issue in Catalyst 5.66
+            # NOTE: Omit 'MyApp::Model' to avoid a component lookup issue in Catalyst 5.66
             user_class: MyAppDB::User
             # This is the name of the field in your 'users' table that contains the user's name
             user_field: username
@@ -415,15 +414,21 @@ you could have a C<User> controller with both C<login> and C<logout>
 actions.  Remember, Catalyst is designed to be very flexible, and leaves
 such matters up to you, the designer and programmer.
 
-Then open C<lib/MyApp/Controller/Login.pm> and add:
+Then open C<lib/MyApp/Controller/Login.pm>, locate the C<sub index : 
+Private> method (this was automatically inserted by the helpers when we 
+created the Login controller above), and delete this line:
 
-    =head2 default
+    $c->response->body('Matched MyApp::Controller::Login in Login.');
+
+Then update it to match:
+
+    =head2 base
     
     Login logic
     
     =cut
     
-    sub default : Private {
+    sub index : Private {
         my ($self, $c) = @_;
     
         # Get the username and password from form
@@ -454,24 +459,46 @@ at the login page but receive an error message.  If the C<username> and
 C<password> values are not present in the form, the user will be taken
 to the empty login form.
 
+Note that we could have used something like C<sub default :Private>; 
+however, the use of C<default> actions is discouraged because it does
+not receive path args as with other actions.  The recommended practice 
+is to only use C<default> in C<MyApp::Controller::Root>.
+
+Another options would be to use something like 
+C<sub base :Path :Args(0) {...}> (where the C<...> refers to the login 
+code shown in C<sub index : Private> above). We are using C<sub base 
+:Path :Args(0) {...}> here to specifically match the URL C</login>. 
+C<Path> actions (aka, "literal actions") create URI matches relative to 
+the namespace of the controller where they are defined.  Although 
+C<Path> supports arguments that allow relative and absolute paths to be 
+defined, here we use an empty C<Path> definition to match on just the 
+name of the controller itself.  The method name, C<base>, is arbitrary. 
+We make the match even more specific with the C<:Args(0)> action 
+modifier -- this forces the match on I<only> C</login>, not 
+C</login/somethingelse>.
+
 Next, create a corresponding method in C<lib/MyApp/Controller/Logout.pm>:
 
-    =head2 default
+    =head2 base
     
     Logout logic
     
     =cut
     
-    sub default : Private {
+    sub index : Private {
         my ($self, $c) = @_;
     
         # Clear the user's state
         $c->logout;
     
-        # Send the user to the starting
+        # Send the user to the starting point
         $c->response->redirect($c->uri_for('/'));
     }
 
+As with the login controller, be sure to delete the 
+C<$c->response->body('Matched MyApp::Controller::Logout in Logout.');>
+line of the C<sub index>.
+
 
 =head2 Add a Login Form TT Template Page
 
@@ -506,7 +533,8 @@ This is generally done via an C<auto> action/method (prior to Catalyst
 v5.66, this sort of thing would go in C<MyApp.pm>, but starting in
 v5.66, the preferred location is C<lib/MyApp/Controller/Root.pm>).
 
-Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert the following method:
+Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert
+the following method:
 
     =head2 auto
     
@@ -540,9 +568,8 @@ Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert the foll
 
 B<Note:> Catalyst provides a number of different types of actions, such
 as C<Local>, C<Regex>, and C<Private>.  You should refer to
-L<Catalyst::Manual::Intro|Catalyst::Manual::Intro> for a more detailed
-explanation, but the following bullet points provide a quick
-introduction:
+L<Catalyst::Manual::Intro> for a more detailed explanation, but the
+following bullet points provide a quick introduction:
 
 =over 4
 
@@ -559,9 +586,9 @@ C<default>, C<index>, and C<auto>.
 
 =item *
 
-Unlike the other private C<Private> actions where only a single method
-is called for each request, I<every> auto action along the chain of
-namespaces will be called.
+Unlike the other actions where only a single method is called for each 
+request, I<every> auto action along the chain of namespaces will be 
+called.
 
 =back
 
@@ -625,30 +652,30 @@ C<myapp_server.pl> script.)
 Now trying going to L<http://localhost:3000/books/list> and you should
 be redirected to the login page, hitting Shift+Reload if necessary (the
 "You are already logged in" message should I<not> appear -- if it does,
-click the C<logout> button and try again).  Make note of the
-C<***Root::auto User not found...> debug message in the development
-server output.  Enter username C<test01> and password C<mypass>, and you
-should be taken to the Book List page.
+click the C<logout> button and try again). Note the C<***Root::auto User
+not found...> debug message in the development server output.  Enter
+username C<test01> and password C<mypass>, and you should be taken to
+the Book List page.
 
-Open C< root/src/books/list.tt2> and add the following lines to the bottom:
+Open C<root/src/books/list.tt2> and add the following lines to the
+bottom:
 
     <p>
       <a href="[% Catalyst.uri_for('/login') %]">Login</a>
       <a href="[% Catalyst.uri_for('form_create') %]">Create</a>
     </p>
 
-Reload your browser and you should now see a "Login" link at the bottom
-of the page (as mentioned earlier, you can update template files without
-reloading the development server).  Click this link to return to the
-login page.  This time you I<should> see the "You are already logged in"
-message.
+Reload your browser and you should now see a "Login" and "Create" links 
+at the bottom of the page (as mentioned earlier, you can update template 
+files without reloading the development server).  Click the first link 
+to return to the login page.  This time you I<should> see the "You are 
+already logged in" message.
 
 Finally, click the C<You can logout here> link on the C</login> page.
 You should stay at the login page, but the message should change to "You
 need to log in to use this application."
 
 
-
 =head1 USING PASSWORD HASHES
 
 In this section we increase the security of our system by converting
@@ -660,8 +687,10 @@ tutorial will function normally.
 Note that even with the techniques shown in this section, the browser
 still transmits the passwords in cleartext to your application.  We are
 just avoiding the I<storage> of cleartext passwords in the database by
-using a SHA-1 hash.  If you are concerned about cleartext passwords
-between the browser and your application, consider using SSL/TLS.
+using a SHA-1 hash. If you are concerned about cleartext passwords
+between the browser and your application, consider using SSL/TLS, made
+easy with the Catalyst plugin 
+L<Catalyst::Plugin:RequireSSL|Catalyst::Plugin:RequireSSL>.
 
 
 =head2 Get a SHA-1 Hash for the Password
@@ -676,6 +705,13 @@ dirty" way to do this:
     e727d1464ae12436e899a726da5b2f11d8381b26
     $
 
+B<Note:> You should probably modify this code for production use to
+not read the password from the command line.  By having the script
+prompt for the cleartext password, it avoids having the password linger
+in forms such as your C<.bash_history> files (assuming you are using
+BASH as your shell).  An example of such a script can be found in
+Appendix 3.
+
 
 =head2 Switch to SHA-1 Password Hashes in the Database
 
@@ -715,7 +751,7 @@ C<password_hash_type> are new, everything else is the same):
             # This is the model object created by Catalyst::Model::DBIC from your
             # schema (you created 'MyAppDB::User' but as the Catalyst startup
             # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::User').
-            # NOTE: Omit 'MyAppDB::Model' to avoid a component lookup issue in Catalyst 5.66
+            # NOTE: Omit 'MyApp::Model' to avoid a component lookup issue in Catalyst 5.66
             user_class: MyAppDB::User
             # This is the name of the field in your 'users' table that contains the user's name
             user_field: username
@@ -739,16 +775,23 @@ You should now be able to go to L<http://localhost:3000/books/list> and
 login as before.  When done, click the "Logout" link on the login page
 (or point your browser at L<http://localhost:3000/logout>).
 
-=head1 AUTHOR
+B<Note:> If you receive the debug screen in your browser with a 
+C<Can't call method "stash" on an undefined value...> error message,
+make sure that you are using v0.07 of 
+L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>.
+The following command can be a useful way to quickly dump the version number
+of this module on your system:
 
-Kennedy Clark, C<hkclark@gmail.com>
+    perl -MCatalyst::Plugin::Authorization::ACL -e 'print $Catalyst::Plugin::Authorization::ACL::VERSION, "\n";'
 
-Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark. All rights reserved.
+=head1 AUTHOR
 
-This library is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
+Kennedy Clark, C<hkclark@gmail.com>
 
-Version: .94
+Please report any errors, issues or suggestions to the author.  The
+most recent version of the Catlayst Tutorial can be found at
+L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Runtime/lib/Catalyst/Manual/Tutorial/>.
 
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).