【问题标题】:validating user/updating table验证用户/更新表
【发布时间】:2011-06-20 22:06:04
【问题描述】:

我有简单的密码重置结构,用户可以在丢失时更新他们现有的密码。用户转到他们输入电子邮件的链接,为忘记密码的用户创建一个令牌并将其存储在指定的表中。一封电子邮件会发送给用户,其中包含一个附加了令牌的链接,当他们点击该链接时,它会将他们带到一个页面以重置他们的密码。如果存储在数据库中的令牌与$_GET 中的令牌匹配,我允许他们重置密码。很简单。

问题是我无法更新他们在数据库中的特定行。我试图通过检查他们在数据库中输入的电子邮件来识别他们。我可以更新整个表的密码行,但是当指定一个用户时它会失败。

if(isset($_POST['sub_settings'])){

    $query = "SELECT * FROM `Password_Reset` WHERE `token` = '".$token."' AND `email` = '".$user_email."'";
    $request = mysql_query($query,$connection) or die(mysql_error());
    $result = mysql_fetch_array($request);

    $token = $result['token'];
    $alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz1234567890";
    $rand = str_shuffle($alpha);
    $salt = substr($rand,0,40);
    $hashed_password = sha1($salt . $_POST['password']);
    $user_email = $result['email'];



    if($_GET['token'] == $token) {
        header("Location: index.php");
        exit;

    }else{

    if(empty($_POST['Password'])) {
        $valid = false;
        $error_msgs[] = 'Whoops! You must enter a password.';
    }

    if($_POST['Password'] != $_POST['passwordConfirm'] || empty($_POST['Password'])) {
        $valid = false;
        $error_msgs[] = "Your password entries didn't match...was there a typo?";
    }

    if($valid) {
        $query = "UPDATE `Users` SET `encrypted_password` = '$hashed_password' WHERE `Email` = '$user_email'";

        mysql_query($query,$connection);
    }


    }
}

提前非常感谢

【问题讨论】:

    标签: php mysql html passwords reset


    【解决方案1】:

    为什么不将用户 ID 存储在 Password_Reset 表中,然后根据那里的 ID 更新用户,而不是尝试匹配那里的电子邮件。

    请注意,如果您尝试匹配用户电子邮件,则电子邮件大小写必须与查询中的“=”完全匹配。您可以将电子邮件地址小写,但这在技术上是不正确的。

    $query = "
        SELECT *
        FROM `Password_Reset`
        WHERE `token` = '".$token."' AND LOWER(`email`) = LOWER('".$user_email."')
    ";
    

    【讨论】:

      【解决方案2】:

      您似乎没有大写 $_POST['Password']

      $hashed_password = sha1($salt . $_POST['password']);
      

      根据您的其他代码,应该是:

      $hashed_password = sha1($salt . $_POST['Password']);
      

      同样在您的 SELECT 中,您有 email,在您的 UPDATE 中您使用 Email. MySQL 在非 Windows 平台上默认区分大小写。

      【讨论】:

      • 谢谢,这肯定会有所帮助,但不是罪魁祸首。
      【解决方案3】:

      您的第一个查询中似乎有 $user_email,但它尚未设置,因为您正在使用第一个查询的结果设置它。除非你的意思是$_POST['user_email']

      使用 user_id 会更容易、更安全,并且仅在用户实际在您的系统中时才向用户发送令牌(看来您正在向每个人发送令牌!)

      您的令牌应该是唯一的。看起来它是完全随机的。制作令牌的一个好方法是创建一个随机字符串 + 唯一标识用户的内容(例如他们的用户名或电子邮件),然后使用 MD5 或类似函数对其进行哈希处理。它相当安全,并且可以识别用户本身,因此您可以仅通过令牌查找它们。

      【讨论】:

        【解决方案4】:
         if($_GET['token'] == $token) {
                header("Location: index.php");
                exit;
        

        我想应该是!=。 您需要检查令牌是否不等于进入数据库的令牌。不是吗?

        【讨论】:

        • 是的,我这样做是为了测试。需要换回来谢谢
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 2013-02-25
        • 2023-03-23
        • 1970-01-01
        相关资源
        最近更新 更多