Skip to main content

CakePHP Auth Component Implementation


First time I was using Auth component of CakePHP and it took me around 2 complete days to fully understand Auth component and implement it. Documenation is also bit confusing on http://book.cakephp.org/1.3/. I am writing this post for my future reference as well as for those who are having doubts with Auth component. Let's start

1) Very first step is to include Auth component in components array of AppController. As you know for controllers we do most of the common stuff in AppController.

app_controller.php
 
var $components = array('Auth');

2) If you wanna customize Auth component messages and variables use beforeFilter() method for that, as :
     
app_controller.php

function beforeFilter() {
               
                 //it would load User model dynamically. Discussed in detail in step 4
                 $this->Auth->authenticate = ClassRegistry::init('User');
                               
                 //Following is the code to change default variables for username and password
                 //default array is 
                 //var $fields = array('username' => 'username', 'password' => 'password');
                 $this->Auth->fields = array(
                            'username' => 'username',
                            'password' => 'cslab_user_password'
                  );
                  //You can change the default login from /users/login to be any action of your choice.
                  //$this->Auth->loginAction    = array('admin' => false, 'controller' => 'users', 'action' => 'login');
                  //The AuthComponent remembers what controller/action pair you were trying to get to before you were asked to authenticate yourself by storing this value in the Session, under the Auth.redirect key. However, if this session value is not set (if you're coming to the login page from an external link, for example), then the user will be redirected to the URL specified in loginRedirect.
                  $this->Auth->loginRedirect  = array('admin' => false, 'controller' => 'assigned_devices', 'action' => 'index');
                  //You can also specify where you want the user to go after they are logged out, with the default being the login action.
                  $this->Auth->logoutRedirect = array('admin' => false, 'controller' => 'users', 'action' => 'login');
                 //Change the default error message displayed when someone does not successfully log in.                       
                 $this->Auth->loginError     = 'Username/Password Mismatch.';
                //Change the default error message displayed when someone attempts to access an object or action to which they do not have access.                      
                $this->Auth->authError      = 'Please login to view that page.';
 
                 //I have written these three function to check if admin or normal user is logged in and to get username  of the logged in member
                  $this->set('admin',$this->_isAdmin());
                  $this->set('loggedIn',$this->_loggedIn());
                  $this->set('username',$this->_usersUsername());
}

//Checks if user loggedin is an admin
function _isAdmin(){
           $admin = false;
           if($this->Auth->user('role') == ADMIN_ROLE) {
                     $admin = true;
           }
           return $admin;
}
//Checks if user is logged in        
function _loggedIn(){
            $logged_in = false;
            if($this->Auth->user()) {
                         $logged_in = true;
            }
            return $logged_in;
}

//finds username of the loggedin user
function _usersUsername(){
             $users_username = null;
             if($this->Auth->user()){
                       $users_username = $this->Auth->User('username');
             }
             return $users_username;
}

3) Go to your Users controller and write a login() function. 

users_controller.php 
 
function login(){
              //No need to write anything inside function because Auth component handles everything.
}

If you don't wanna customize anything leave it blank otherwise write your code inside. For example  I wanna implement validations on username and password so here is my code : 

function login(){
                  if($this->data){
                             $this->User->set($this->data);
                             if($this->User->validates()){
                                         if ($this->Auth->user()) {
                                                        $this->redirect($this->Auth->redirect());
                                         }
                              }else{
                                          $this->errors = $this->User->validationErrors;
                              }
                    }
                    $this->set('errors',$this->errors);
 }

4) Now write view file :

login.ctp

<?php  echo $session->flash('auth');?> //Display auth messages

<?php  echo $this->Form->create("User"); ?>

<?php echo $this->Form->input("username", array('label' => "Username : ", 'type' => 'text', 'class' => 'tal vat w200p', 'error' => false)); ?><br/>

<?php echo $this->Form->input("pswd", array('label' => "Password : ", 'type' => 'password', 'class' => 'tal vat w200p', 'error' => false)); ?><br/>

<?php echo $this->Html->div("pb10p",$this->Html->link("I forgot my password","/users/forgot",array('class' => 'pl150p')), array('id' => "forgot_password")); ?>

<?php echo $this->Form->end(" Login ",array('class' => 'button')); ?>

Have you noticed i have used "pswd" field name instead of "password" for password field. It's because if we will use "password" field then it would perform automatic hashing even if the field is empty and would skip validation for password as well. I just wanna perform password validation and md5 hashing without salt. So we have to use other name for password field and overwrite hasing. So go to User model and write validation code as well as hashPasswords() function. We also have to set  'authenticate' to the object you're authenticating against (usually this is User, done in step 2) 

user.php
 
var $validate    =   array(
                 'username' => array(
                                'username_should_not_be_empty' => array(
                                                'rule'                      => 'notEmpty',
                                                 'message'            => 'Please Enter Username',
                                                 'last'                       => true
                                 )
                    ),
                    'pswd' => array(
                                    'password_should_not_be_empty' => array(
                                                     'rule'                      => 'notEmpty',
                                                     'message'            => 'Please Enter Password',
                                                      'last'                       => true
                                     )
                     )
);

function hashPasswords($data) {
                if (isset($data['User']['pswd'])) {
                               $data['User']['cslab_user_password'] = md5($data['User']['pswd']);
                                return $data;
                 }
                 return $data;
}


5) To logout from system you have to just write following function :

users_controller.php

function logout(){
               $this->redirect($this->Auth->logout());
}

6) If you wanna another page to get accessed without login, mention it in beforeFilter() function of the controller. For example i also wants to access register and forgot_password functions of users controller  to be accessed publicly then write following code :

users_controller.php

function beforeFilter(){
                parent::beforeFilter();
                $this->Auth->allow('register', 'forgot_password');
 }  

7) You can also your own layout for Authentication error messages like 'authError' and 'loginError' using following line in AppController beforeFilter() function.

message_error.ctp

$this->Auth->flashElement    = "message_error";

this layout file should be saved as ......app\views\elements\message_error.ctp
 
//    Code in /app/views/elements/message_error.ctp
<div class="ui-state-error">
    <?php echo $message; ?>
</div>

8) If you wanna get any information of the loggedin used then you can get it simple as :

$user_email = $this->Auth->user('user_email');

where 'user_email' is users table field.

That's it. If you have any doubt regarding please post your comments below. 


Reference Links : 
 





Thanks!!!!!!!!!! Enjoy Programming :)

Comments

Popular posts from this blog

Odoo/OpenERP: one2one relational field example

one2one relational field is deprecated in OpenERP version>5 but you can achieve the same using many2one relational field. You can achieve it in following two ways : 1) using many2one field in both the objects ( http://tutorialopenerp.wordpress.com/2014/04/23/one2one/ ) 2)  using inheritance by deligation You can easily find the first solution with little search over internet so let's start with 2nd solution. Scenario :  I want to create a one2one relation between two objects of openerp hr.employee and hr.employee.medical.details What I should do  i. Add _inherits section in hr_employee class ii. Add field medical_detail_id in hr_employee class class hr_employee(osv.osv):     _name = 'hr.employee'     _inherits = {' hr.employee.medical.details ': "medical_detail_id"}     _inherit = 'hr.employee'         _columns = {             ...

How to draw Dynamic Line or Timeseries Chart in Java using jfreechart library?

Today we are going to write a code to draw a dynamic timeseries-cum-line chart in java.   The only difference between simple and dynamic chart is that a dynamic event is used to create a new series and update the graph. In out example we are using timer which automatically calls a funtion after every 1/4 th second and graph is updated with random data. Let's try with the code : Note : I had tried my best to provide complete documentation along with code. If at any time anyone have any doubt or question please post in comments section. DynamicLineAndTimeSeriesChart.java import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Timer; import javax.swing.JPanel; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.XYPlot; import...

pyodbc.OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]

Recently, I faced this error in our Docker-Container environment. All the necessary packages were already installed but still, I was facing this clueless error. I search a bit and after an hour and so I found the exact reason and solution for this error. To know more about this error in detail. Please follow this Github thread. https://github.com/mkleehammer/pyodbc/issues/610 https://github.com/mkleehammer/pyodbc/issues/610#issuecomment-587523802 Solution: It's because the   server's certificate has too weak a key. In case you are using Linux env directly/not the Docker one.  Just edited /etc/ssl/openssl.cnf and change these 2 lines. MinProtocol = TLSv1.0 CipherString = DEFAULT@SECLEVEL=1 In case you are also using a container, please add these three lines to your Docker file. RUN chmod +rwx /etc/ssl/openssl.cnf RUN sed -i ' s/TLSv1.2/TLSv1/g ' /etc/ssl/openssl.cnf RUN sed -i ' s/SECLEVEL=2/SECLEVEL=1/g ' /etc/ssl/openssl.cnf Thanks!! Enjoy Programming! Refer...