Как заменить алгоритм хеширования паролей CakePHP? - PullRequest
6 голосов
/ 21 февраля 2009

У меня есть существующая база данных, над которой я пытаюсь поместить приложение для торта. Старое приложение использовало crypt () в Perl для хэширования паролей. Мне нужно сделать то же самое в приложении PHP.

Где правильное место, чтобы сделать это изменение в стандартном приложении cakephp? И как бы выглядело такое изменение?

Ответы [ 3 ]

8 голосов
/ 22 февраля 2009

Я получил это работает ...

вот мой AppController:

class AppController extends Controller {
    var $components = array('Auth');

    function beforeFilter() {
        // this is part of cake that serves up static pages, it should be authorized by default
        $this->Auth->allow('display');
        // tell cake to look on the user model itself for the password hashing function
        $this->Auth->authenticate = ClassRegistry::init('User');
        // tell cake where our credentials are on the User entity
        $this->Auth->fields = array(
           'username' => 'user',
           'password' => 'pass',
        );
        // this is where we want to go after a login... we'll want to make this dynamic at some point
        $this->Auth->loginRedirect = array('controller'=>'users', 'action'=>'index');
    }
}

Тогда вот пользователь:

<?php
class User extends AppModel {
    var $name = 'User';

    // this is used by the auth component to turn the password into its hash before comparing with the DB
    function hashPasswords($data) {
         $data['User']['pass'] = crypt($data['User']['pass'], substr($data['User']['user'], 0, 2));
         return $data;
    }
}
?>

Все остальное нормально, я думаю.

Вот хороший ресурс: http://teknoid.wordpress.com/2008/10/08/demystifying-auth-features-in-cakephp-12/

2 голосов
/ 03 мая 2012

На самом деле описанный выше метод danb не работал для меня в CakePHP 2.x Вместо этого я закончил тем, что создал пользовательский компонент аутентификации, чтобы обойти стандартный алгоритм хеширования:

/ приложение / Controller / Компонент / Auth / CustomFormAuthenticate.php

<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');

class CustomFormAuthenticate extends FormAuthenticate {

    protected function _password($password) {
        return self::hash($password);
    }

    public static function hash($password) {
        // Manipulate $password, hash, custom hash, whatever
        return $password;
    }
}

... а затем используйте это в моем контроллере ...

public $components = array(
    'Session',
    'Auth' => array(
        'authenticate' => array(
            'CustomForm' => array(
                'userModel' => 'Admin'
            )
        )
    )
);

Этот последний блок также может быть помещен в beforeFilter метод AppController . В моем случае я просто решил поместить его специально в один контроллер, где я собирался использовать пользовательскую аутентификацию с другой моделью пользователя.

1 голос
/ 21 октября 2013

Просто чтобы следовать этому в CakePHP 2.4.1, я создавал интерфейс для устаревшей базы данных, в которой существующие пароли пользователей сохранялись как md5 (accountnumber: statictext: password), и чтобы пользователи могли войти в систему, нам нужно используйте эту систему хеширования.

Решение было:

Создайте файл приложения / Controller / Component / Auth / CustomAuthenticate.php с помощью:

<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');

class CustomAuthenticate extends FormAuthenticate {

    protected function _findUser($username, $password = null) {
        $userModel = $this->settings['userModel'];
        list(, $model) = pluginSplit($userModel);
        $fields = $this->settings['fields'];

        if (is_array($username)) {
            $conditions = $username;
        } else {
            $conditions = array(
                $model . '.' . $fields['username'] => $username
            );

        }

        if (!empty($this->settings['scope'])) {
            $conditions = array_merge($conditions, $this->settings['scope']);

        }

        $result = ClassRegistry::init($userModel)->find('first', array(
            'conditions' => $conditions,
            'recursive' => $this->settings['recursive'],
            'contain' => $this->settings['contain'],
        ));
        if (empty($result[$model])) {
            return false;
        }

        $user = $result[$model];
        if ($password) {
            if (!(md5($username.":statictext:".$password) === $user[$fields['password']])) {
                return false;
            }
            unset($user[$fields['password']]);
        }

        unset($result[$model]);
        return array_merge($user, $result);
    }

}

"extends FormAuthenticate" означает, что этот файл принимает на себя функцию _findUser, но переходит к FormAuthenticate для всех других функций, как обычно. Затем это активируется путем редактирования AppController.php и добавления в класс AppController что-то вроде этого:

public $components = array(
    'Session',
    'Auth' => array(
        'loginAction' => array('controller' => 'accounts', 'action' => 'login'),
        'loginRedirect' => array('controller' => 'accounts', 'action' => 'index'),
        'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),
        'authenticate' => array (
            'Custom' => array(
                'userModel' => 'Account',
                'fields' => array('username' => 'number'),
            )
        ),
    )
);

В частности, обратите внимание на использование ключа ассоциативного массива 'Custom'.

Наконец, при создании нового пользователя необходимо хешировать пароль, поэтому к файлу модели (в моем случае Account.php) я добавил:

public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password'])) {
        $this->data[$this->alias]['password'] = md5($this->data[$this->alias]['number'].":statictext:".$this->data[$this->alias]['password']);
    }
    return true;
}
...