【问题标题】:CakePHP 2: Override AuthComponent's "password" methodCakePHP 2:覆盖 AuthComponent 的“密码”方法
【发布时间】:2012-07-15 14:47:28
【问题描述】:

我的目标是为每个用户提供唯一的盐,而不是为每个用户只使用Configure::read('Security.salt')

我知道 CakePHP 2.x 不再自动散列密码。这允许我对密码执行模型验证,这非常好。但是,我看不到可以覆盖 AuthComponent 的“密码”方法的方法。因此,即使我可以控制密码在保存到数据库之前的哈希方式,但我无法控制在执行实际登录时密码的哈希方式。来自食谱:

您无需在调用之前对密码进行哈希处理 $this->Auth->login().

如何使$this->Auth->login() 使用自定义的密码散列方法?

谢谢。

更新:我最终选择了 Hannibal Lecter 博士的回答(创建自定义身份验证对象)。操作方法如下:

旧代码:

$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email')));

新代码(将“表单”更改为“自定义”):

$this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email')));

创建“app/Controller/Component/Auth/CustomAuthenticate.php”并使其如下所示:

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

class CustomAuthenticate extends FormAuthenticate {
}

从“lib/Cake/Controller/Component/Auth/BaseAuthenticate.php”复制“_findUser”和“_password”方法并将它们粘贴到“CustomAuthenticate”类中。然后对“_findUser”方法进行如下两处修改:

  1. 从“$conditions”数组中删除这一行:$model . '.' . $fields['password'] =&gt; $this-&gt;_password($password),

  2. if (empty($result) || empty($result[$model])) {更改为if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this-&gt;_password($password, $result[$model]['id'])) {

然后对“_password”方法进行如下两处修改:

  1. 通过将protected function _password($password) {更改为protected function _password($password, $id) {来创建“$id”参数

  2. 通过将return Security::hash($password, null, true);更改为return Security::hash($password, null, Configure::read('Security.salt') . $id);来更新盐值

最后,更新所有出现的AuthComponent::password 以使用Security::hash,其逻辑与上述相同。

【问题讨论】:

    标签: cakephp authentication passwords


    【解决方案1】:

    您是否考虑过不使用 Auth->login() 调用,而是使用模型中当前实现的代码? (http://api20.cakephp.org/view_source/auth-component#line-506) 你可以重写它以满足你的需要。

    【讨论】:

    • 我不确定该怎么做,而且这似乎不是一种对开发人员非常友好的方式。为每个用户提供独特的盐绝对不是一个不寻常的目标。你有一些示例代码吗?不管怎样,我很感激你的时间
    【解决方案2】:

    您可能可以创建一个custom auth object 并随意散列密码。查看existing auth objects 以大致了解它们的工作原理。

    【讨论】:

    • 成功了!我用相关代码更新了我的问题。谢谢!
    【解决方案3】:

    如果任何人想详细了解为什么对每个密码加盐是哈希密码的正确方法(带有代码示例),请访问此处:http://crackstation.net/hashing-security.htm

    也许对这里发布的代码稍作改进是采纳我刚刚链接到的文章的建议,并在每次用户创建帐户或更改密码时生成一个“新随机盐”......“。 "

    此处发布的实现使用原始 Auth 的硬编码静态盐加上用户 ID 作为盐的组合,这意味着每个用户在更改密码时都会重新使用相同的盐。因此,如果您想遵循此散列指南的建议,您需要在用户每次创建/更改密码时生成一个新的随机盐,并且必须将该唯一盐与散列密码一起存储在用户表中。

    你可以使用他们的随机盐生成器:

    define("PBKDF2_SALT_BYTES", 24);
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    

    按照惯例,将其存储在 users 表中名为“salt”的新字段中。由于代码已经为您提供了用户 ID,您可以随时根据需要存储/查找 salt。

    文章中还提到了“慢散列函数”一节,它使用一种称为“密钥拉伸”的技术,以及如何使用 PBKDF2 或 bcrypt 等标准算法来实现。提供了 PHP 代码示例,可以将其复制并粘贴到您的自定义 Auth 实现中以增加安全性。

    CakePHP 开发人员 Mark Story 发布了一篇关于如何implement bcrypt in CakePHP's Auth 的博客文章

    在 cmets 部分,Mark Story 评论说 CakePHP 2.3 将有一些新的内置特性来生成 bcrypt 哈希。

    【讨论】:

      【解决方案4】:

      至少在 cake 2.3 中已经使用了一个独特的盐,即使你的配置值中的盐总是相同的。我不确定旧版本是否也是如此。

      您也可以使用 Configure::write("Security.salt", $superAwesomeUserSpecificSalt); 来更改 User 模型中 beforeSave() 函数中的盐值;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        • 1970-01-01
        • 2014-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多