我已经搜索了。除了该文件中的最后两个查询外,我在网站上有多个查询功能。我只是找不到/弄清楚它。精疲力竭。
我已经创建了重置密码功能。用户放入他们的电子邮件,如果在我的数据库中找到该电子邮件,则会将重置令牌发送到该电子邮件。单击电子邮件中的重置链接后,它会指向包含电子邮件和令牌信息的重置密码页面。
除了表未更新之外,其他所有功能均应正常运行。我想用ipaddress和新密码更新idaccount表。我想在使用的列中使用ipaddress和“ UsedToken”更新重置表。 (通过这种方式,我可以重复使用该表。如果用户更改了登录帐户的密码并请求了电子邮件/令牌,则显示特定的数据。)最终,我想根据“已使用”列来设计无法重用令牌的代码。不为空,并验证令牌是否确实已使用。
更改密码的基本HTML表单:
<body>
<form id="forgotpwdreset" name="forgotpwdreset" method="post" action="" onsubmit="forgotpwdalert()"<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>
<table border="0">
<tr></tr>
<tr></tr>
<input type="hidden" name="email" value="<?php echo $email; ?>" />
<input type="hidden" name="token" value="<?php echo $token; ?>" />
Password must be at least 8 characters long and contain at least 1 number AND 1 capital letter.<br /><br />
<tr>New Password: <align="center"><input required type="password" name="newpassword" id="newpassword" placeholder="" pattern="(?=.*\d)(?=.*[A-Z]).{8,}"> <input type="checkbox" onclick="togglepassword()"> Show Password<br /><br />
<tr></tr><br />
<tr>Confirm Password: <align="center"><input required type="password" name="newpassword2" id="newpassword2" placeholder="" pattern="(?=.*\d)(?=.*[A-Z]).{8,}" onchange="confirmpwd()"><br />
<tr></tr><br />
<tr>
<tr></tr><br />
<tr><align="center"><input type="submit" name="pwdresetsubmit" id="pwdresetsubmit" value="Reset Password" onclick="return confirmpwd()" />  
<tr></tr><br />
</table>
</form>
</body>
PHP处理表单:
<?php
include 'insert.php';
if(isset($_SESSION['ondashsession'])){
$session = $_SESSION['ondashsession'];
$sql = "SELECT * FROM ondash_idaccount WHERE ID = '$session'";
$result = mysqli_query($dbcon, $sql) or die("Error");
while($row = mysqli_fetch_assoc($result)){
echo "You are already logged in, " . $row['firstname'] . "." . "<br />";
}
}else{
if (isset($_POST['pwdresetsubmit'])) {
$newpassword2 = $_POST['newpassword2'];
$ipaddress = $_SERVER['REMOTE ADDR'];
// Grab token and email that came from the email link
$token = $_GET['token'];
$email = $_GET['email'];
//echo "Token: " . $token . "<br />" . "Email: " . $email; //returns correct info working properly.
// select email address of user from the password_reset table
$sqlnewpass = "SELECT * FROM password_resets WHERE token='$token' AND email='$email'";
$results = mysqli_query($dbcon, $sqlnewpass);
if (mysqli_num_rows($results) > 0 ){
$row = mysqli_fetch_assoc($results);
// print_r($row['email']); //returns correct result
// print_r("# of rows: " . $numrows); //returns correct result
//WORKS UP TO HERE...WORKS UP TO HERE...WORKS UP TO HERE...WORKS UP TO HERE...WORKS UP TO HERE...WORKS UP TO HERE...
$sql2 = "UPDATE ondash_idaccount SET `password`=?, `ipaddress`=? WHERE `email`='$email'";
$stmt2 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt2, $sql2)){
echo "SQL error" . $dbcon->error;
}else{
$hashedpassword = password_hash($newpassword2, PASSWORD_DEFAULT);
//var_dump($hashedpassword); //generating hash pwd works but not updating database
mysqli_stmt_bind_param($stmt2, "ss", $hashedpassword, $ipaddress);
mysqli_stmt_execute($stmt2);
$stmt2->close();
error_reporting(E_ALL);
// echo "SQL 2 error" . $dbcon->error; //No errors reporting
$UsedToken = 'UsedToken';
"UPDATE password_resets SET `used`='$UsedToken', `ipaddress`='$ipaddress' WHERE `token`='$token' AND `email`='$email'";
}
}
}
?>
这两个表都没有更新。我想念什么?对于这个新手的任何帮助,将不胜感激。
更新:
由于输入错误,第一个查询被暂停。我有$_SERVER['REMOTE ADDR'];
。请注意_丢失。因此,整个查询停止,没有错误。更改为$_SERVER['REMOTE_ADDR'];
,瞧!发现这是一个恶臭。基本上,我用一些标签回显了每个变量,以了解正在显示的内容,并注意到ipaddress为空!
第二个查询仍然不确定发生了什么。但是,遵循一个很好的建议来绑定参数(无论如何我都应该这样做),我重写了代码(最后一次无效!)来这样做。再次,瞧!
我正在发布更新的代码。希望它对接收和更新与密码重置令牌相关的问题有用。我还实现了不能重复使用令牌的策略。所有的作品都像野兽!
更新的PHP:
<?php
include 'insert.php';
if(isset($_SESSION['ondashsession'])){
$session = $_SESSION['ondashsession'];
$sql = "SELECT * FROM ondash_idaccount WHERE ID = '$session'";
$result = mysqli_query($dbcon, $sql) or die(mysqli_error($dbcon));
while($row = mysqli_fetch_assoc($result)){
echo "You are already logged in, " . $row['firstname'] . "." . "<br />";
}
}else{
//Check if token has already been used
$token = $_GET['token'];
$email = $_GET['email'];
$sqlused = "SELECT * FROM password_resets WHERE token='$token' AND email='$email'";
$resultsused = mysqli_query($dbcon, $sqlused);
if (mysqli_num_rows($resultsused) > 0 ){
$row = mysqli_fetch_assoc($resultsused);
//echo $row['used'];
if($row['used'] == 'UsedToken'){
echo "<strong>That reset link has already been used. Please request another.</strong>";
}else{
if (isset($_POST['pwdresetsubmit'])) {
error_reporting(E_ALL);
$newpassword2 = $_POST['newpassword2'];
$ipaddress = $_SERVER['REMOTE_ADDR'];
// Grab token and email that came from the email link
$token = $_GET['token'];
$email = $_GET['email'];
// select data from password_reset table
$sqlnewpass = "SELECT * FROM password_resets WHERE token='$token' AND email='$email'";
$results = mysqli_query($dbcon, $sqlnewpass);
if (mysqli_num_rows($results) > 0 ){
$row = mysqli_fetch_assoc($results);
//update user password in database
$sql2 = "UPDATE ondash_idaccount SET `password`=?, `ipaddress`=? WHERE `email`='$email'";
$stmt2 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt2, $sql2)){
echo "SQL error" . $dbcon->error;
}else{
$hashedpassword = password_hash($newpassword2, PASSWORD_DEFAULT);
//var_dump($hashedpassword); //generating hash pwd works but not updating database
mysqli_stmt_bind_param($stmt2, "ss", $hashedpassword, $ipaddress);
mysqli_stmt_execute($stmt2);
$stmt2->close();
echo "<strong>Password successfully reset!</strong>";
//Update pwd reset table
$UsedToken = 'UsedToken';
$sql3 = "UPDATE password_resets SET `used`=?, `ipaddress`=? WHERE `token`='$token' AND `email`='$email'";
$stmt3 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt3, $sql3)){
echo "SQL error" . $dbcon->error;
}else{
mysqli_stmt_bind_param($stmt3, "ss", $UsedToken, $ipaddress);
mysqli_stmt_execute($stmt3);
$stmt3->close();
// echo "SQL 2 error" . $dbcon->error; //No errors reporting
// echo $row['email'] . $row['ipaddress'];
答案 0 :(得分:1)
更新:
由于输入错误,第一个查询被暂停。我有$_SERVER['REMOTE ADDR'];
。请注意_丢失。因此,整个查询停止,没有错误。更改为$_SERVER['REMOTE_ADDR'];
,瞧!发现这是一个恶臭。基本上,我用一些标签回显了每个变量,以了解正在显示的内容,并注意到ipaddress为空!
第二个查询仍然不确定发生了什么。但是,遵循一个很好的建议来绑定参数(无论如何我都应该这样做),我重写了代码(最后一次无效!)来这样做。再次,瞧!
我正在发布更新的代码。希望它对接收和更新与密码重置令牌相关的问题有用。我还实现了不能重复使用令牌的策略。所有的作品都像野兽!
更新的PHP:
<?php
include 'insert.php';
if(isset($_SESSION['ondashsession'])){
$session = $_SESSION['ondashsession'];
$sql = "SELECT * FROM ondash_idaccount WHERE ID = '$session'";
$result = mysqli_query($dbcon, $sql) or die(mysqli_error($dbcon));
while($row = mysqli_fetch_assoc($result)){
echo "You are already logged in, " . $row['firstname'] . "." . "<br />";
}
}else{
//Check if token has already been used
$token = $_GET['token'];
$email = $_GET['email'];
$sqlused = "SELECT * FROM password_resets WHERE token='$token' AND email='$email'";
$resultsused = mysqli_query($dbcon, $sqlused);
if (mysqli_num_rows($resultsused) > 0 ){
$row = mysqli_fetch_assoc($resultsused);
//echo $row['used'];
if($row['used'] == 'UsedToken'){
echo "<strong>That reset link has already been used. Please request another.</strong>";
}else{
if (isset($_POST['pwdresetsubmit'])) {
error_reporting(E_ALL);
$newpassword2 = $_POST['newpassword2'];
$ipaddress = $_SERVER['REMOTE_ADDR'];
// Grab token and email that came from the email link
$token = $_GET['token'];
$email = $_GET['email'];
// select data from password_reset table
$sqlnewpass = "SELECT * FROM password_resets WHERE token='$token' AND email='$email'";
$results = mysqli_query($dbcon, $sqlnewpass);
if (mysqli_num_rows($results) > 0 ){
$row = mysqli_fetch_assoc($results);
//update user password in database
$sql2 = "UPDATE ondash_idaccount SET `password`=?, `ipaddress`=? WHERE `email`='$email'";
$stmt2 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt2, $sql2)){
echo "SQL error" . $dbcon->error;
}else{
$hashedpassword = password_hash($newpassword2, PASSWORD_DEFAULT);
//var_dump($hashedpassword); //generating hash pwd works but not updating database
mysqli_stmt_bind_param($stmt2, "ss", $hashedpassword, $ipaddress);
mysqli_stmt_execute($stmt2);
$stmt2->close();
echo "<strong>Password successfully reset!</strong>";
//Update pwd reset table
$UsedToken = 'UsedToken';
$sql3 = "UPDATE password_resets SET `used`=?, `ipaddress`=? WHERE `token`='$token' AND `email`='$email'";
$stmt3 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt3, $sql3)){
echo "SQL error" . $dbcon->error;
}else{
mysqli_stmt_bind_param($stmt3, "ss", $UsedToken, $ipaddress);
mysqli_stmt_execute($stmt3);
$stmt3->close();
// echo "SQL 2 error" . $dbcon->error; //No errors reporting
// echo $row['email'] . $row['ipaddress'];
}
}
}
}
}
}
}
}
?>
答案 1 :(得分:0)
您的PHP代码中似乎没有明显的错误。
我在这里运行了一个简化版本:
$newpassword2 = "TESTME";
$ipaddress = "127.0.0.1";
$token = "my_token";
$email = "email@email.com";
$sqlnewpass = "SELECT * FROM tmp_password_resets WHERE token='$token' AND
email='$email'";
$results = mysqli_query($dbcon, $sqlnewpass);
if (mysqli_num_rows($results) > 0 ){
$row = mysqli_fetch_assoc($results);
$sql2 = "UPDATE tmp_ondash_idaccount SET `password`=?, `ipaddress`=? WHERE `email`='$email'";
$stmt2 = mysqli_stmt_init($dbcon);
if(!mysqli_stmt_prepare($stmt2, $sql2)){
echo "SQL error" . $dbcon->error;
}else{
$hashedpassword = "MY_HASHED_PASSWORD";
mysqli_stmt_bind_param($stmt2, "ss", $hashedpassword, $ipaddress);
mysqli_stmt_execute($stmt2);
$stmt2->close();
$UsedToken = 'UsedToken';
}
}
这成功运行了UPDATE。我建议您检查一下: *传入变量:电子邮件实际上是否与两个表中的行都匹配?它们是相同的数据类型吗?不区分大小写? *表结构:这些字段的大小和类型适合传入的字符串吗?
此外,我注意到您正在混合使用mysqli预准备语句的过程和OOP风格。您是否考虑过使用PDO连接器来保持一致性?需要注意的是:在某些区域中,您正在使用bindParam,但在其他区域则没有(SQL注入!)。据我所知,无论哪种情况,您实际上都可以使用bindValue。