使用php和MySQL创建密码重置页面很困难

时间:2017-06-12 16:19:12

标签: php mysql

下午。

我正在尝试使用php创建密码重置页面。单击重置按钮后,我获得了密码重置成功消息,但未对我的数据库进行任何更改。

任何帮助都将不胜感激。

<?php
  session_start();
  $_SESSION['message'] = '';
  $mysqli = new mysqli("localhost", "User", "password", "DarrenOBrien");

  if ($_SESSION['loggedin']) {
    if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

      $email=$_SESSION('email');
      $result = $mysqli->query("SELECT * FROM accounts WHERE userEmail='$email'") or die($mysqli->error);

      $user = $result->fetch_assoc();
        if (password_verify($_POST['oldpassword'], $user['userPassword'])) {
          if (($_POST['newpassword'] == $_POST['confirmnewpassword'])) {
            $newpass=password_hash($_POST['confirmnewpassword'], PASSWORD_BCRYPT);
            $sql = "UPDATE accounts SET userPassword='$newpass' WHERE userEmail='$email'";
            $_SESSION['message'] = 'Password reset successful';
          }
          else {
            $_SESSION['message'] = 'Passwords do not match. Please try again.';
          }
        }
        else {
          $_SESSION['message'] = 'Old password does not match password in records. Please try again.';
        }



    }
  }
  else {
    header('location: register.php');
  }

?>


<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Login</title>
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <link rel="stylesheet" href="css/styles.css">
</head>

<body>
  <!--Navbar-->
   <nav class="navbar navbar-inverse">
     <div class="container">
       <div class="navbar-header">
         <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
           <span class="sr-only">Toggle navigation</span>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
         </button>
         <a class="navbar-brand" href="welcome.php">PHP Project </a>
       </div>
       <div id="navbar" class="collapse navbar-collapse">
         <ul class="nav navbar-nav">
           <li><a href="welcome.php">Home</a></li>
           <li class="active"><a href="profile.php">Profile</a></li>
           <li><a href="products.php">Products</a></li>
         </ul>
         <a href="logout.php" class="navbar-brand pull-right">Logout</a>
       </div>
     </div>
   </nav>
   <!--End of Navbar-->


   <div class="container-fluid" id="profile">
     <form action="reset.php" method="post" enctype="multipart/form-data" autocomplete="off">
      <div class="alert-error"><?= $_SESSION['message'] ?></div>

       <div class="form-group">
         <label for="oldpass">Old Password:</label>
         <input type="password" class="form-control" id="oldpass" placeholder="Password" name="oldpassword" autocomplete="new-password" minlength="4" required />
       </div>

       <div class="form-group">
         <label for="newpass">New Password:</label>
         <input type="password" class="form-control" id="newpass" placeholder="Password" name="newpassword" autocomplete="new-password" minlength="4" required />
       </div>

       <div class="form-group">
         <label for="confirmnewpass">Confirm New Password:</label>
         <input type="password" class="form-control" id="confirmnewpass" placeholder="Password" name="confirmnewpassword" autocomplete="new-password" minlength="4" required />
       </div>

       <input type="submit" value="Reset Password" name="reset" class="btn btn-block btn-primary" id="resetbtn"/>
     </form>
   </div>

<!-- Required bootstrap scripts -->
  <script src="js/jquery-3.2.1.min.js"></script>
  <script src="js/bootstrap.min.js"></script>
<!-- End of required bootstrap scripts -->
</body>

3 个答案:

答案 0 :(得分:0)

使用

 $reuslt = $mysqli->query("UPDATE accounts SET userPassword='$newpass' 
    WHERE userEmail='$email'");
    if ($result) {
     $_SESSION['message'] = 'Password reset successful';
    } else {
     $_SESSION['message'] = 'Passwords do not match. Please try again.';
    }

因为没有查询,你刚刚准备了sql格式,并没有将它发送到数据库。

答案 1 :(得分:0)

我想直接关注这段代码

if (($_POST['newpassword'] == $_POST['confirmnewpassword'])) {
        $newpass=password_hash($_POST['confirmnewpassword'], PASSWORD_BCRYPT);
        $sql = "UPDATE accounts SET userPassword='$newpass' WHERE 
        userEmail='$email'";
        $_SESSION['message'] = 'Password reset successful';
      }

这里你的$ sql变量包含一个sql语句,即一个当前什么都不做的纯文本字符串,你必须执行它,就像你执行上面的select查询一样

if ($mysqli->query($sql) === TRUE) {
    $_SESSION['message'] = 'Password reset successful'; 
} else {
    $_SESSION['message'] = "Error updating record: " . $mysqli->error;
}

取自w3Schools

此外,如果这是您的端点的整个范围,您应该记得关闭连接,调用mysqli类实例的close方法

最后但同样重要的是,我强烈建议您不要使用类名(mysqli)作为您的实例名称($ mysqli),只是为了良好的实践

修改

收到的评论确实是对的,我的答案在这一点上很差,所以让我们考虑一些事情

你应该使用预准备语句,而不是直接在sql查询中抛出变量,聪明的人可以使用它来将sql语句注入数据库

如果我错了,请纠正我,但这样可以更加安全:

//Email select query part
$email= $mysqli->real_escape_string($_SESSION['email']);
$stmt = $mysqli->prepare("SELECT * FROM accounts WHERE userEmail=(?)")
if (!$stmt->bind_param("s", mysqli->$email)) {
    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
    //handle error code, disrupt execution...
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
    //handle error code, disrupt execution...
}


//Update part
$newpass=password_hash(
    $mysqli->real_escape_string($_POST['confirmnewpassword']),
    PASSWORD_BCRYPT);
$stmt = mysqli->prepare("UPDATE accounts SET userPassword=(?) WHERE 
userEmail=(?)");
if (!$stmt->bind_param("ss", $newpass,$email)) {
    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
    //handle error code, disrupt execution...
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
    //handle error code, disrupt execution...
}
$_SESSION['message'] = 'Password reset successful';

现在我确信这可以用更有效的方式进行重构,但我希望我帮助OP了解他的代码是什么

答案 2 :(得分:0)

您忘记运行密码更新查询: 所以,插入这个:

$updated = $mysqli->query($sql) or die($mysqli->error);

之后:

$sql = "UPDATE accounts SET userPassword='$newpass' WHERE userEmail='$email'";

编辑1 - 如何使用mysqli库准备和运行查询:

选项1:使用mysqli_stmt_get_result() + mysqli_fetch_array()

<?php

/*
 * Run prepared db queries.
 * 
 * Uses:
 *      - mysqli_prepare()
 *      - mysqli_stmt_bind_param()
 *      - mysqli_stmt_execute()
 *      - mysqli_stmt_get_result()
 *      - mysqli_fetch_array()
 */

try {
    $username = 'Hello';
    $password = 'World';

    //---------------------------------------------------------
    // Connect to db.
    //---------------------------------------------------------
    $conn = mysqli_connect('<host>', '<user>', '<pass>', '<db>');
    if (!$conn) {
        throw new Exception('Connect error: ' . mysqli_connect_errno() . ' - ' . mysqli_connect_error());
    }

    //---------------------------------------------------------
    // Sql statement.
    //---------------------------------------------------------
    $query = "SELECT * FROM users WHERE username = ? AND password = ?";

    //---------------------------------------------------------
    // Prepare sql statement.
    //---------------------------------------------------------
    $stmt = mysqli_prepare($conn, $query);
    if (!$stmt) {
        throw new Exception('The sql statement can not be prepared!');
    }

    //---------------------------------------------------------
    // Bind variables to the prepared statement as parameters.
    //---------------------------------------------------------
    $bound = mysqli_stmt_bind_param($stmt, 'ss', $username, $password);
    if (!$bound) {
        throw new Exception('The variables could not be bound to the prepared statement!');
    }

    //---------------------------------------------------------
    // Execute the prepared statement.
    //---------------------------------------------------------
    $executed = mysqli_stmt_execute($stmt);
    if (!$executed) {
        throw new Exception('The prepared statement could not be executed!');
    }

    //---------------------------------------------------------
    // Get the result set from the prepared statement.
    //---------------------------------------------------------
    $result = mysqli_stmt_get_result($stmt);
    if (!$result) {
        throw new Exception(mysqli_error($conn));
    }

    //---------------------------------------------------------
    // Get the number of rows in statements result set.
    //---------------------------------------------------------
    $rows = mysqli_num_rows($result);

    if ($rows > 0) {
        //---------------------------------------------------------
        // Read the result set.
        //---------------------------------------------------------
        $row = mysqli_fetch_array($result, MYSQLI_ASSOC);
        if (!isset($row)) {
            echo 'No records returned!';
            exit();
        }

        echo 'Login successful: ' . $row['username'] . '/' . $row['password'];
    } else {
        echo 'Invalid username/password. Please check and retry login.';
    }

    //-----------------------------------------------------------
    // Frees stored result memory for the given statement handle.
    //-----------------------------------------------------------
    mysqli_stmt_free_result($stmt);

    //---------------------------------------------------------
    // Close db connection.
    //---------------------------------------------------------
    $closed = mysqli_close($conn);
    if (!$closed) {
        throw new Exception('The database connection can not be closed!');
    }
} catch (Exception $exception) {
    echo '<pre>' . print_r($exception, true) . '</pre>';
    exit();
}


选项2:使用mysqli_stmt_store_result() + mysqli_stmt_bind_result() + mysqli_stmt_fetch()

<?php

/*
 * Run prepared db queries.
 * 
 * Uses:
 *      - mysqli_prepare()
 *      - mysqli_stmt_bind_param()
 *      - mysqli_stmt_execute()
 *      - mysqli_stmt_store_result()
 *      - mysqli_stmt_bind_result()
 *      - mysqli_stmt_fetch()
 */

try {
    $username = 'Hello';
    $password = 'World';

    //---------------------------------------------------------
    // Connect to db.
    //---------------------------------------------------------
    $conn = mysqli_connect('<host>', '<user>', '<pass>', '<db>');
    if (!$conn) {
        throw new Exception('Connect error: ' . mysqli_connect_errno() . ' - ' . mysqli_connect_error());
    }

    //---------------------------------------------------------
    // Sql statement.
    //---------------------------------------------------------
    $query = "SELECT * FROM users WHERE username = ? AND password = ?";

    //---------------------------------------------------------
    // Prepare sql statement.
    //---------------------------------------------------------
    $stmt = mysqli_prepare($conn, $query);
    if (!$stmt) {
        throw new Exception('The sql statement can not be prepared!');
    }

    //---------------------------------------------------------
    // Bind variables to the prepared statement as parameters.
    //---------------------------------------------------------
    $bound = mysqli_stmt_bind_param($stmt, 'ss', $username, $password);
    if (!$bound) {
        throw new Exception('The variables could not be bound to the prepared statement!');
    }

    //---------------------------------------------------------
    // Execute the prepared statement.
    //---------------------------------------------------------
    $executed = mysqli_stmt_execute($stmt);
    if (!$executed) {
        throw new Exception('The prepared statement could not be executed!');
    }

    //---------------------------------------------------------
    // Transfer the result set from the prepared statement.
    //---------------------------------------------------------
    $stored = mysqli_stmt_store_result($stmt);
    if (!$stored) {
        throw new Exception('The result set from the prepared statement could not be transfered!');
    }

    //---------------------------------------------------------
    // Get the number of rows in statements' result set.
    //---------------------------------------------------------
    $rows = mysqli_stmt_num_rows($stmt);

    if ($rows > 0) {
        //---------------------------------------------------------
        // Bind result set columns to corresponding variables.
        //---------------------------------------------------------
        $bound = mysqli_stmt_bind_result($stmt, $resId, $resUsername, $resPassword);
        if (!$bound) {
            throw new Exception('The result set columns could not be bound to the variables');
        }

        //--------------------------------------------------------------------
        // Fetch results from the prepared statement into the bound variables.
        //--------------------------------------------------------------------
        while (mysqli_stmt_fetch($stmt)) {
            echo 'Successfully returned data:<br/><br/>';
            echo 'ID: ' . $resId . '<br/>';
            echo 'Username: ' . $resUsername . '<br/>';
            echo 'Password: ' . $resPassword . '<br/>';
        }
    } else {
        echo 'Invalid username/password. Please check and retry login!';
    }

    //-----------------------------------------------------------
    // Free stored result memory for the given statement handle.
    //-----------------------------------------------------------
    mysqli_stmt_free_result($stmt);

    //---------------------------------------------------------
    // Close db connection.
    //---------------------------------------------------------
    $closed = mysqli_close($conn);
    if (!$closed) {
        throw new Exception('The database connection can not be closed!');
    }
} catch (Exception $exception) {
    echo '<pre>' . print_r($exception, true) . '</pre>';
    exit();
}

Nota bene: 尝试将mysqli_stmt_store_result()mysqli_stmt_get_result()一起使用会导致错误。