If you are new to CakePHP, you will be attracted by this example to copy the code to your key business scenarios or sensitive data processing applications. Note: This chapter discusses the internal working mechanism of Cake.
CakePHP user authentication instance
Example: Simple user authentication
Section 1 Big Picture
If you are new to CakePHP, you will be attracted by this example to copy the code to your key business scenarios or sensitive data processing applications. Note: This chapter discusses the internal working mechanism of Cake, not the application security module. I'm not sure if I have provided some obvious security vulnerabilities. the purpose of this example is to show how Cake handles security issues internally and how you can create independent "bullet proof clothing" for your own applications"
The access control of Cake is based on the built-in ACL engine, but what is the persistence of user authentication and authentication information?
We found that the user authentication modules vary with various application systems. Some users prefer the ciphertext password after hash encoding, some prefer LDAP authentication, and the User model is always slightly different for each system. We leave this part of work to you. Will this change in future versions? We are not sure yet, because it is not worthwhile to incorporate the user authentication module into the framework. it is very easy to create your own user authentication system.
You need to do three things:
User authentication method (typically used to verify the user's identity, such as the user name/password combination)
Method of tracking user access (usually Session)
Check whether the user has passed the authentication (usually interaction with the Session)
In this example, we will create a simple user authentication system for a customer management system. Such a virtual project is used to manage customer contact information and related customer records. All functions except a few public views used to display customer names and roles must pass user authentication before access.
We start with how to verify users who attempt to access the system. The authenticated user information is stored in the PHP Session by the Cake session Component. After obtaining user information from the session, we can determine which operations can be performed by the user.
One thing to note: authentication is not a synonym for access control. What we are doing now is to check whether the user is actually the user he claims and allow him to access the functions of the corresponding part. If you want to adjust such access more specifically, refer to the previous ACL section. We think ACL is suitable for such scenarios, but now we only focus on the simplest user authentication.
I also want to express it again. This does not mean that this example can only serve the most basic application security. We just want to provide you with enough vegetables to build your own "bullet-proof clothing ".
Section 2 authentication and persistence
First, we need a way to persist user information. In this customer management system, we use databases to persist user information:
Table 'users', Fictional Client Management System Database
Create table 'users '(
'Id' int (11) not null auto_increment,
'Username' varchar (255) not null,
'Password' varchar (32) not null,
'First _ name' varchar (255) not null,
'Last _ name' varchar (255) not null,
Primary key ('id ')
)
Very simple, right? Our User model is also simple:
Class User extends AppModel
{
Var $ name = 'user ';
}
?>
The first step is to complete the login view and action. This provides users with a login portal and an opportunity to process user information and determine whether the system can be accessed. Using HTML helper, you can easily create the Form:
/App/views/users/login. thtml
The login credentials you supplied cocould not be recognized. Please try again.
/App/views/users/login. thtml
The login credentials you supplied cocould not be recognized. Please try again.
For this simple view, you also need an action (/users/login). The code is as follows:
/App/controllers/users_controller.php (partial)
Class UsersController extends AppController
{
Function login ()
{
$ This-> set ('error', false );
// If a user has submitted form data:
If (! Empty ($ this-> data ))
{
// First, let's see if there are any users in the database
// With the username supplied by the user using the form:
$ Someone = $ this-> User-> findByUsername ($ this-> data ['user'] ['username']);
// At this point, $ someone is full of user data, or its empty.
// Let's compare the form-submitted password with the one in
// The database.
If (! Emptyempty ($ someone ['user'] ['password']) & $ someone ['user'] ['password'] = $ this-> data ['user'] ['password'])
{
// Note: hopefully your password in the DB is hashed,
// So your comparison might look more like:
// Md5 ($ this-> data ['user'] ['password']) =...
// This means they were the same. We can now build some basic
// Session information to remember this user as 'loged'-in '.
$ This-> Session-> write ('user', $ someone ['user']);
// Now that we have them stored in a session, forward them on
// To a landing page for the application.
$ This-> redirect ('/clients ');
}
// Else, they supplied incorrect data:
Else
{
// Remember the $ error var in the view? Let's set that to true:
$ This-> set ('error', true );
}
}
}
Function logout ()
{
// Redirect users to this action if they click on a Logout button.
// All we need to do here is trash the session information:
$ This-> Session-> delete ('user ');
// And we shoshould probably forward them somewhere, too...
$ This-> redirect ('/');
}
}
?>
/App/controllers/users_controller.php (partial)
Class UsersController extends AppController
{
Function login ()
{
// Don't show the error message if no data has been submitted.
$ This-> set ('error', false );
// If a user has submitted form data:
If (! Empty ($ this-> data ))
{
// First, let's see if there are any users in the database
// With the username supplied by the user using the form:
$ Someone = $ this-> User-> findByUsername ($ this-> data ['user'] ['username']);
// At this point, $ someone is full of user data, or its empty.
// Let's compare the form-submitted password with the one in
// The database.
If (! Empty ($ someone ['user'] ['password']) & $ someone ['user'] ['password'] = $ this-> data ['user'] ['password'])
{
// Note: hopefully your password in the DB is hashed,
// So your comparison might look more like:
// Md5 ($ this-> data ['user'] ['password']) =...
// This means they were the same. We can now build some basic
// Session information to remember this user as 'loged'-in '.
$ This-> Session-> write ('user', $ someone ['user']);
// Now that we have them stored in a session, forward them on
// To a landing page for the application.
$ This-> redirect ('/clients ');
}
// Else, they supplied incorrect data:
Else
{
// Remember the $ error var in the view? Let's set that to true:
$ This-> set ('error', true );
}
}
}
Function logout ()
{
// Redirect users to this action if they click on a Logout button.
// All we need to do here is trash the session information:
$ This-> Session-> delete ('user ');
// And we shoshould probably forward them somewhere, too...
$ This-> redirect ('/');
}
}
?>
Not bad: If you write concise points, the code should not exceed 20 lines. The result of this action is as follows:
1. the user passes authentication, saves the information to the Session, and forwards it to the system homepage.
2. if the authentication fails, the system returns to the logon page and displays the relevant error information.
Section 3 access verification
Now we can authenticate users so that the system can kill users who want to access non-public content without logging in.
One way is to add a function to the controller to check the session status.
/App/app_controller.php
Class AppController extends Controller
{
Function checkSession ()
{
// If the session info hasn't been set...
If (! $ This-> Session-> check ('user '))
{
// Force the user to login
$ This-> redirect ('/users/login ');
Exit ();
}
}
}
?>
/App/app_controller.php
Class AppController extends Controller
{
Function checkSession ()
{
// If the session info hasn't been set...
If (! $ This-> Session-> check ('user '))
{
// Force the user to login
$ This-> redirect ('/users/login ');
Exit ();
}
}
}
?>
Now you have a function that ensures that unlogged users cannot access restricted system content. you can control it at any level. The following are some examples:
All actions must be authenticated
Class NotesController extends AppController
{
// Don't want non-authenticated users looking at any of the actions
// In this controller? Use a beforeFilter to have Cake run checkSession
// Before any action logic.
Function beforeFilter ()
{
$ This-> checkSession ();
}
}
?>
Authentication is required in a separate action.
Class NotesController extends AppController
{
Function publicNotes ($ clientID)
{
// Public access to this action is okay...
}
Function edit ($ noteId)
{
// But you only want authenticated users to access this action.
$ This-> checkSession ();
}
}
?>
All actions must be authenticated
Class NotesController extends AppController
{
// Don't want non-authenticated users looking at any of the actions
// In this controller? Use a beforeFilter to have Cake run checkSession
// Before any action logic.
Function beforeFilter ()
{
$ This-> checkSession ();
}
}
?>
Authentication is required in a separate action.
Class NotesController extends AppController
{
Function publicNotes ($ clientID)
{
// Public access to this action is okay...
}
Function edit ($ noteId)
{
// But you only want authenticated users to access this action.
$ This-> checkSession ();
}
}
?>
You have mastered some basic knowledge and can start to implement custom or advanced functions. We recommend that you integrate the ACL control of Cake.