authenticationcakephpblowfishcakephp-2.xcakephp-2.7

Invalid username or password at login() using BlowfishPasswordHasher in CakePHP 2.x


I'm using CakePHP 2.7.8 to build an admin panel. My project contains multiple admins instead of users. That's why I have an admins table in the database and not an users table.

I'm using BlowfishHasher for hashing passwords, and it's working fine. Passwords are hashed before saving to database.

But login() returns:

Invalid username or password, try again

Table admins:

CREATE TABLE `admins` (
  `id` char(36) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `gender` varchar(45) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`))

Admins model : Admin.php

<?php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher','Controller/Component/Auth');
/**
 * Admin Model
 *
 */
class Admin extends AppModel {

/**
 * Display field
 *
 * @var string
 */

    public $displayField = 'first_name';


        public function beforeSave($options = array()) {
            if(isset($this->data[$this->alias]['password'])){
                $passwordHasher = new BlowfishPasswordHasher();
                $this->data[$this->alias]['password'] = $passwordHasher->hash(
                    $this->data[$this->alias]['password']
                        );
            }
            return true;
        }
}

Admins Controller : AdminsController.php

<?php
App::uses('AppController', 'Controller');
/**
 * Admins Controller
 *
 * @property Admin $Admin
 * @property PaginatorComponent $Paginator
 * @property FlashComponent $Flash
 * @property SessionComponent $Session
 */
class AdminsController extends AppController {

/**
 * Components
 *
 * @var array
 */
    public $components = array('Paginator', 'Flash', 'Session');

/**
 * index method
 *
 * @return void
 */
    public function index() {
        $this->Admin->recursive = 0;
        $this->set('admins', $this->Paginator->paginate());
    }
/**
 * login function
 */
        public function login(){
            if($this->request->is('post')) {
                if($this->Auth->login()) {
                    return $this->redirect($this->Auth->redirectUrl());
                }
                $this->Flash->error(__('Invalid username or password, try again'));
            }
        }

/**
 * logout function
 */
        public function logout(){
            return $this->redirect($this->Auth->logout());
        }
}

App Controller : AppController.php

<?php
App::uses('Controller', 'Controller');

/**
 * @package     app.Controller
 * @link        http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller {

    public $components = array(
        'Flash',
        'Auth' => array(
            'loginRedirect'=>array(
                'controller'=>'admins',
                'action'=>'index'
            ),
            'logoutRedirect'=>array(
                'controller'=>'admins',
                'action'=>'login'
            ),
            'authenticate'=>array(
                'Form'=>array(
                    'passwordHasher'=>'Blowfish'
                )
            )
        )
    );

    function beforeFilter() {
        $this->Auth->authenticate = array(
            AuthComponent::ALL => array(
                'userModel' => 'Admin'
            )
        );
        $this->Auth->allow('login','add','index');
    }
}

Login view : login.ctp

<div class="users form">
    <?php echo $this->Flash->render('auth'); ?>
    <?php echo $this->Form->create('admin'); ?>
        <fieldset>
        <legend>
            <?php echo __('Please enter your username and password'); ?>
        </legend>
        <?php 
            echo $this->Form->input('username'); 
            echo $this->Form->input('password');
        ?>
    </fieldset>
    <?php echo $this->Form->end(__('Login')); ?>
</div>

Solution

  • Try changing your password field from VARCHAR(255) to BINARY(60).

    Remember to clear your models cache after doing so.

    See the following question for further details:


    Edit

    Also the AuthComponent configuration defined in the $components array is being overwritten in beforeFilter().

    Try replacing the following code:

    $this->Auth->authenticate = array(
        AuthComponent::ALL => array(
            'userModel' => 'Admin'
        )
    );
    

    with:

    $this->Auth->authenticate[AuthComponent::ALL] = array(
        'userModel' => 'Admin'
    );
    

    Edit 2

    In your view, you have to replace

    <?php echo $this->Form->create('admin'); ?>
    

    with

    <?php echo $this->Form->create('Admin'); ?>
    

    Case is important.