【问题标题】:How can we check if a password doesn't exist in the DB? [closed]我们如何检查数据库中是否不存在密码? [关闭]
【发布时间】:2021-02-19 10:25:03
【问题描述】:

我按照 MVC 设计模式在 PHP 7 和 MySQL 5 中开发了一个 Web 应用程序。我正在研究注册系统,我遇到了 password_verify 方法的问题。事实上,在插入用户的个人资料之前,我会检查数据库中是否不存在密码。这是我的代码:

 public function signUp($name, $firstname, $profilePicture, $phone, $email, $password, $passwordConfirmation)
    {
        $userData = $this->_userDAO->getUsersDataByEmail($email);
        if (isset($name) && isset($firstname)
            && isset($profilePicture)
            && isset($phone) && isset($email)
            && isset($password) && isset($passwordConfirmation)) {
            if ($userData == false) {
                if (password_verify($password, $userData["password"]) == false) {
                    if (preg_match("/^0[1-9]([0-9]{2}){4}$/", $phone)) {
                        if (preg_match("/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@\/+=!?&*#<>_]).{8,}$/", $password)) {
                            if ($password == $passwordConfirmation) {
                                $this->_userDAO->addUser($name, $firstname, $profilePicture, $phone, $email, password_hash($password, PASSWORD_DEFAULT));
                                $this->_membersDAO->addMember();
                                header("Location:index.php");
                            } else {
                                echo "Les mots de passe ne se correspondent pas, veuillez réssayer s'il vous plaît !";
                            }
                        } else {
                            echo "Votre mot de passe doit contenir au moins un chiffre, une lettre minuscule, une majuscule ainsi qu'un 
                     symbole spéciale et être d'une longueur supérieure à 8 caractères !";
                        }
                    } else {
                        echo "Veuillez saisir un numéro de téléphone valide !";
                    }
                    } else {
                    echo "Le mot de passe saisie est déjà utilisé ! Veuillez en choisir un autre !";
                }


            } else {
                echo "L'email saisie est déjà utilisé, veuillez en saisir un autre !";
            }

        }
    }

   public function getUsersByEmail($email)
    {
        $sql = "SELECT * FROM `users` WHERE email = ?";
        $userEmail = $this->queryRow($sql, $email);

        return $userEmail;
    }

public function addUser($name, $firstname, $profilePicture, $phone, $email, $password)
{
    $column = ["name", "firstname", "profile_picture", "phone", "email", "password"];
    $values = ["'$name'", "'$firstname'", "'$profilePicture'", "'$phone'", "'$email'", "'$password'"];
    $this->insertRow("users", $column, $values);
}

public function queryRow($sql, $param = null) { 
try { 
$request = $this->request($sql, $param); 
$data = $request->fetch(PDO::FETCH_ASSOC); 
$request->closeCursor(); } 
catch (PDOException $e) { 
die("Erreur : " . $e->getMessage()); } 
return $data; 
} 

但是,当我执行脚本时,用户的数据被注册,而用户输入的密码已经存在于数据库中。

你能帮我解决这个问题吗?

【问题讨论】:

  • 两个用户的密码相同有什么关系?
  • queryRow 做什么/返回?
  • 我知道两个用户可以使用相同的密码和两封不同的电子邮件,但我想让所有用户都是唯一的,以执行注册系统规则。
  • 所有传入的参数都将被设置/声明,因此这些isset() 调用都不是必需的。如果您正在检查 null 值,则无需函数调用即可完成。 /^0[1-9]([0-9]{2}){4}$/ 更简单地表示为/^0[1-9]\d{8}$/。当值包含单引号时,addUser() 看起来注定要崩溃。
  • 如果您现在说两个用户可以有不同的电子邮件,但密码相同,那么这似乎是正确的......但是现在您的问题不清楚。请不要将问题详细信息添加为 cmets;所有相关的细节都应该在问题中。

标签: php mysql authentication passwords


【解决方案1】:

当你使用php的密码散列系统时,你不能使用SQL来判断一个密码是否唯一。为什么不?散列系统将随机 salt 应用于每个密码。从根本上说,这种盐的目的是为了让一个密码与另一个密码进行比较,除非在数据库中的每个密码上使用password_verify() php 和密码散列的工作方式将采取每个密码约 250 毫秒。这是一个令人望而却步的时间。这就是重点:散列和验证密码故意是一个 CPU 密集型过程,以减缓网络蠕动。

一般来说,每个用户都应该能够选择自己的密码。如果您告诉用户某个特定密码已经存在于您的系统中,则属于安全违规。

我从未听说过强制密码唯一性的系统(我听说过很多系统)。您确实需要强制用户名唯一性,无论是通过使用电子邮件地址作为用户名,还是通过拒绝预先存在的用户名。

当您创建新用户时,只需在该密码上使用password_hash() 即可获取要放入数据库中用户行的值。

【讨论】:

  • 感谢您的回答。我已更改代码以仅强制电子邮件唯一性。
猜你喜欢
  • 2020-07-03
  • 2013-10-06
  • 1970-01-01
  • 2013-06-23
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多