如何替换 cakephp 密码哈希算法?

发布于 2024-07-13 13:55:51 字数 149 浏览 8 评论 0原文

我有一个现有的数据库,我想在其上放置一个蛋糕应用程序。 旧应用程序使用 Perl 中的 crypt() 来散列密码。 我需要在 PHP 应用程序中执行相同的操作。

在标准 cakephp 应用程序中进行更改的正确位置在哪里? 这样的改变会是什么样子呢?

I have an existing database I'm trying to put a cake app on top of. The old app used crypt() in Perl to hash the passwords. I need to do the same in the PHP app.

Where is the correct place to make that change in a standard cakephp app? And what would such a change look like?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江心雾 2024-07-20 13:55:51

我让它工作了...

这是我的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/

I got it working...

here is my 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');
    }
}

Then here is the user:

<?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;
    }
}
?>

Everything else is normal, i think.

Here is a good resource: http://teknoid.wordpress.com/2008/10/08/demystifying-auth-features-in-cakephp-12/

錯遇了你 2024-07-20 13:55:51

实际上 danb 的上述方法在 CakePHP 2.x 中对我不起作用相反,我最终创建了一个自定义身份验证组件来绕过标准哈希算法:

/app/Controller/Component/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'
            )
        )
    )
);

最后一个块也可以放在 AppControllerbeforeFilter 方法中。 就我而言,我只是选择将其专门放在一个控制器中,我将在其中对不同的用户模型使用自定义身份验证。

Actually the above described method by danb didn't work for me in CakePHP 2.x Instead I ended up creating a custom auth component to bypass the standard hashing algorithm:

/app/Controller/Component/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;
    }
}

...and then use that in my controller...

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

This last block can also be put inside the beforeFilter method of the AppController. In my case I just choose to put it specifically in one controller where I was going to use custom authentication with a different user model.

丶情人眼里出诗心の 2024-07-20 13:55:51

为了在 CakePHP 2.4.1 中跟进,我正在为旧数据库构建一个前端,该数据库将现有用户密码存储为 md5(帐号:静态文本:密码),并且为了允许用户登录,我们需要使用该哈希系统也是如此。

解决方案是:

创建一个文件 app/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);
    }

}

“扩展 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;
}

Just to follow this up in CakePHP 2.4.1, I was building a front-end for a legacy database that had existing user passwords stored as md5(accountnumber:statictext:password), and to allow users to login we needed to use that hashing system as well.

The solution was:

Create a file app/Controller/Component/Auth/CustomAuthenticate.php with:

<?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);
    }

}

The "extends FormAuthenticate" means that this file takes over the _findUser function but defers to FormAuthenticate for all other functions as normal. This is then activated by editing AppController.php and adding to the AppController class something like this:

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'),
            )
        ),
    )
);

In particular note the use of the associative array key 'Custom'.

Finally it's necessary to hash the password when creating a new user, so to the model file (in my case Account.php) I added:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文