CakePHP Auth component: login with username or e-mail

CakePHP proved to be a nice flexible and lightweight framework. When I try to bend it a little to perform something unusual it almost always turns out ok. Below an example of a custom login action that will allow users to login with their username OR e-mail (CakePHP 1.3). The action goes into the Users controller.

/**
 * Log in with username OR e-mail
 *
 *  @param void
 */
function login() {
 
  // login with username or e-mail
  if (!empty($this->Auth->data)) {
 
    // save username entered in the login form
    $username = $this->Auth->data['User']['username'];
 
    // find a user by e-mail
    $this->User->contain();
    $find_by_email = $this->User->find('first', array(
        'conditions' => array('email' => $this->Auth->data['User']['username']),
        'fields' => 'username'
      )
    );
 
    // found
    if (!empty($find_by_email)) {
 
      // retry login with e-mail instead of username
      $this->Auth->data['User']['username'] = $find_by_email['User']['username'];
      if (!$this->Auth->login($this->Auth->data['User'])) {
 
        // login failed
        // bring back the username entered in the login form
        $this->Auth->data['User']['username'] = $username;
      } else {
        // login successful
        // clear flash message
        $this->Session->delete('Message.auth');
 
        // redirect
        if ($this->Auth->autoRedirect) {
          $this->redirect($this->Auth->redirect(), null, true);
        }
      }
    }
  }
}

The view:

<?php echo $form->create('User', array('action' => 'login')); ?>
<fieldset>
  <legend>Login</legend>
  <?php echo $form->input('username', array('label' => 'Username or e-mail:')); ?>
  <?php echo $form->input('password', array('label' => 'Password:')); ?>
</fieldset>
<?php echo $form->end('Login'); ?>

6 Responses to CakePHP Auth component: login with username or e-mail

  • August 4, 2011 at 2:32 pm
    Jawatan Kosong says:

    Instead of $this->User->find(‘first’… I think you could use $this->User->findByEmail($this->Auth->data['User']['username']);

    Nice post anyway.

  • August 4, 2011 at 2:49 pm
    netboy says:

    Thanks, I will consider using the magic find methods more often.

  • March 16, 2012 at 9:50 pm
    Khaled Attia says:

    You can save one query to the database
    Here is my login action (Cakephp 2.0.6)

    public function login()
      {
      if( $this->request->is('post') )
      {
        App::Import('Utility', 'Validation');
        if( isset($this->data['User']['username']) && Validation::email($this->data['User']['username']) )
        {
          $this->request->data['User']['email'] = $this->data['User']['username'];
          $this->Auth->authenticate['Form'] = array('fields' => array('username' => 'email'));
        }
     
        if( ! $this->Auth->login() )
        {
          $this->Session->setFlash(__('Invalid username or password, try again'));
        }
        else
        {
          $this->redirect($this->Auth->redirect());
        }
      }
    }

  • October 15, 2012 at 2:24 pm
    Himanshu says:

    awesome it works with cake 2.2.2 also
    great work

  • Pingback: php « CakePHP Articles

  • March 14, 2013 at 10:41 am
    manish patel says:

    it’s very helpfull !!!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>