【问题标题】:CakePHP Auth Component validation issueCakePHP Auth 组件验证问题
【发布时间】:2011-05-09 20:58:22
【问题描述】:

有些验证问题似乎只在使用 Auth 组件时出现。 我的注册表中有 4 个字段:usernamepasswordpassword_confirmemail

我的用户模型也附加了多重验证行为。以下是适用于注册表的规则:

var $validationSets=array(
    "register" => array(
        "username" => array(
            "usernameFieldNotEmpty" => array(
                "rule" => "notEmpty",
                "message" => "You did not enter the username!"
            ),
            "usernameValid" => array(
                "rule" => "__alphaNumericDashUnderscore",
                "message" => "The username you entered is not valid!"
            ),
            "usernameExistsInDatabase" => array(
                "rule" => array("__existingRecord", false), 
                "message" => "The username you entered has been already registered in our database!"
            )
        ),
        "password" => array(
            "passwordFieldNotEmpty" => array(
                "rule" => "notEmpty",
                "message" => "You did not enter your password!"
            )
        ),
        "password_confirm" => array(
            "passwordConfirmFieldNotEmpty" => array(
                "rule" => "notEmpty",
                "message" => "You did not confirm your password!"
            ),
            "passwordsMatch" => array(
                "rule" => array("__fieldMatch", "password"),
                "message" => "The passwords you entered don't match!"
            )
        ),
        "email" => array(
            "emailFieldNotEmpty" => array(
                "rule" => "notEmpty",
                "message" => "You did not enter the e-mail!"
            ),
            "emailValid" => array(
                "rule" => "email",
                "message" => "The e-mail you entered is not valid!"
            ),
            "emailExistsInDatabase" => array(
                "rule" => array("__existingRecord", false), 
                "message" => "The e-mail you entered has been already registered in our database!"
            )
        )
        /*"language" => array(

        )*/
    )

这是我的注册表:

<?php echo $this->Form->create('User', array('url' => array('controller' => 'users', 'action' => 'register')));?>
<fieldset>
    <legend><?php __('Add User'); ?></legend>
<?php
    echo $this->Form->input('username');
    echo $this->Form->input('password', array('type' => 'password', 'value' => ''));//value='' - resets the password input on any error on the page
    echo $this->Form->input('password_confirm', array('type' => 'password', 'value' => ''));
    echo $this->Form->input('email');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>

现在,每次我提交 EMPTY 表单时,密码字段虽然为空,但通过了所有验证测试(我尝试将 value =&gt; '' 放入代码中,但没有用)。 此外,电子邮件输入似乎通过了'notEmpty' 测试,显示的错误是The email is not valid

我查看了所有代码,但找不到任何解决方案。

【问题讨论】:

  • 你是如何相互核对密码的?
  • 与 auth 一起使用的密码字段永远不会为空,您要做的就是检查 compare_pw 字段是否有效以及哈希版本是否与密码字段匹配。你说你的解决方案是一个黑客是正确的。你可以比较然后像 return Security::hash($this->data['User']['compare'], null, true) === $this->data['User']['password'];
  • 这就是我所做的。实际上,我的问题出在控制器内部,即如何“重置”密码字段。我在下面的“编辑”中弄清楚了。但是我没有使用 Security::hash(),而是使用 $this->Auth->password() 来与 Auth 组件保持一致... :) 另外,一个重要的注意事项是 password 字段将仅当您在表单中还有 username 字段时才进行散列。否则它将保持纯文本。

标签: authentication cakephp validation


【解决方案1】:

我已经设法进行了几次“破解”,所以现在问题已经解决了。 不要认为这是最合适的方法,但它可能会为其他遇到我问题的用户派上用场:

首先,在我的UsersController中,我写了这个sn-p,所以如果密码字段被用户留空,在验证之前将其重置为''

if($this->data['User']['password'] == $this->Auth->password('')){
            $this->data['User']['password'] = '';
        }
        $this->User->set($this->data);
        if($this->User->validates()){ //post validation login }

第二个问题是电子邮件验证。奇怪的是,我通过更改 Multivalidatable Behaviour 中的规则顺序解决了这个问题。所以,来自:

"email" => array(
        "emailFieldNotEmpty" => array(
            "rule" => "notEmpty",
            "message" => "You did not enter the e-mail!"
        ),
        "emailValid" => array(
            "rule" => "email",
            "message" => "The e-mail you entered is not valid!"
        ),
        "emailExistsInDatabase" => array(
            "rule" => array("__existingRecord", false), 
            "message" => "The e-mail you entered has been already registered in our database!"
        )
    )

我现在有:

"email" => array(
            "emailExistsInDatabase" => array(
                "rule" => array("__existingRecord", false), 
                "message" => "The e-mail you entered has been already registered in our database!"
            ),
            "emailValid" => array(
                "rule" => "email",
                "message" => "The e-mail you entered is not valid!"
            ),
            "emailFieldNotEmpty" => array(
                "rule" => "notEmpty",
                "message" => "You did not enter the e-mail!"
            )
        )

我不知道这是否是有意的,但似乎显示的是未满足的 last 规则。按照我的逻辑,规则会按照出现的顺序排列,所以如果第一个不适用,请停止检查并显示它。

我再说一遍,我不知道这是否是正确的方法,但我似乎已经解决了这些问题。

如果你有什么要补充的,请补充!

编辑 在 Cake 1.3 Book 中找到了“官方”解释。它说:

By default CakePHP tries to validate a field using all the validation rules declared for it and returns the error message for the last failing rule. But if the key last is set to true for a rule and it fails, then the error message for that rule is returned and further rules are not validated. So if you prefer to show the error message for the first failing rule then set 'last' => true for each rule.

因此,解决我的问题的另一种方法是按出现顺序设置验证规则,并将last 键添加到规则数组中。

【讨论】:

  • 我建议对 emailExistsInDatabase 验证规则使用内置的 isUnique 规则。
  • 我想知道为什么我没有想到...谢谢! (+1 有用的建议)
  • 也不是调用set,然后验证再保存,只要像if($this->Model->save($this->data))一样调用save(){//yes}否则{//否}
  • 这就是我在第一个实例中所做的,但我认为为“else”分支上的任何其他输出消息打开一扇门会很有用......
【解决方案2】:

关于密码问题:您使用的是什么版本的 CakePHP?

1.2 中的 Auth 组件会自动对您的密码进行哈希处理,因此即使是,它也不会为空。 1.3应该没问题,但不知道是哪个版本的。

【讨论】:

  • 我使用的是 1.3,它仍然会散列它。我已将 value='' 放在视图中,这会整理字段,但验证仍然通过,即使我将字段留空。
【解决方案3】:

http://pastebin.com/xnQ02BCW

这是我会使用的。

【讨论】:

  • 感谢您的回答,但这并不是我想要的。验证规则都写得很好,因为当我禁用 Auth 组件时它们都可以正常工作。主要问题是密码字段始终有一个值,即使我将其留空。而且,电子邮件验证似乎不太正确:即使我将其留空,它也会通过 notEmpty 条件。希望你现在更好地理解我的问题是什么:)
  • 是的。我明白了。在验证之前,即使密码为空,Auth Comp 也会对密码进行哈希处理。我在某个地方读到过这个。将尝试挖掘它如何克服它。
  • 期待您的答复。谢谢!
  • 我试着在 irc 里四处打听。他们要求使用确认密码作为字段。我认为一种方法是。因为空密码的哈希值总是不变的。为什么不添加另一个不等于哈希的规则..
  • 感谢您的帮助。我尝试了类似你提到的东西(写在下面的答案)并且它有效,即使它不是最实用的解决方案......
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多