所以基本上,我試圖做一個簡單但安全的,被遺忘的密碼腳本。如何解決這個PHP忘記密碼腳本?
有兩個腳本,一個允許用戶輸入他們的電子郵件地址。然後,他們會向他們發送帶有鏈接的電子郵件,他們必須訪問以保存新密碼。
第二個腳本是鏈接導向的地方。該腳本保存新密碼。
爲了安全起見,我在我的數據庫中創建了一個名爲'token'的新表。它有三個領域;令牌,電子郵件,使用。令牌是一個由10個字母和數字組成的隨機生成的字符串,電子郵件就是用戶的電子郵件地址,並且使用的是1或0的整數,表示令牌是否已被使用。
一旦閱讀了這兩個腳本,您將能夠更加了解我的結構。它們不會很長,也不會很複雜。
到底哪裏出問題了
好了,只有一個很小的事情去錯了,這是復位password.php腳本中。這是用戶在收到電子郵件後來到的地方。基本上,我輸入一個新的密碼,然後點擊「重置密碼」,但沒有任何反應。沒有顯示錯誤或確認,以及我的數據庫中沒有任何更改。我似乎無法調試此功能,並且一直在尋找並嘗試幾個小時。所有的幫助和建議將不勝感激。
請記住,我仍然是PHP和MySQL的新手。用PHP已經工作了大約8周了,而MySQL只有2
忘記-password.php
<?php
//Forgotten password script
//Variable to save errors
$errors = array();
$email = $_POST['email'];
include 'config.php';
mysql_connect("$db_host", "$db_username", "$db_password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
$query = "SELECT email FROM users WHERE email='" . $email . "'";
$result = mysql_query($query);
$num = mysql_num_rows($result);
if($num==0)
{
echo ("<div style='color:red;'>Email address is not registered</div>");
die();
}
$token = getRandomString(10);
$query = "INSERT INTO tokens (token,email) VALUES ('".$token."','".$email."')";
mysql_query($query);
//function to renerate the token
function getRandomString($length)
{
$validCharacters = "ABCDEFGHIJKLMNPQRSTUXYVWZ123456789";
$validCharNumber = strlen($validCharacters);
$result = "";
for ($i = 0; $i < $length; $i++)
{
$index = mt_rand(0, $validCharNumber - 1);
$result .= $validCharacters[$index];
}
return $result;
}
//Send the reset link to the user
function mailresetlink($to,$token)
{
$subject = "Password Reset";
$message = '
<html>
<head>
<title>Password Reset</title>
</head>
<body>
<p>Click on the given link to reset your password <a href="http://domain.com/reset-password.php?token='.$token.'">Reset Password</a></p>
</body>
</html>
';
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
$headers .= 'From: Password Reset <[email protected]>' . "\r\n";
if(mail($to,$subject,$message,$headers))
{
echo "We have sent the password reset link to your email at <strong>".$to."</strong>";
}
}
//If email is posted, send the email
if(isset($_POST['email']))
{
mailresetlink($email,$token);
}
?>
<table align="center" style="padding-bottom:40px;">
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
<tr>
<td>Email Address: </td>
<td><input type="text" name="email" /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Reset My Password" /></td></tr>
<input type="hidden" name="register" value="TRUE" />
</form>
</table>
復位password.php
<?php
//Reset password script
$token = $_GET['token'];
$email;
include 'config.php';
mysql_connect("$db_host", "$db_username", "$db_password") or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
if(!isset($_POST['newpassword']))
{
$query = "SELECT email FROM tokens WHERE token='" . $token . "' AND used = 0";
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
{
$email = $row['email'];
}
if ($email != '')
{
$_SESSION['email'] = $email;
}
else
{
echo "Invalid link or Password already changed";
}
}
$pass = $_POST['newpassword'];
$email = $_SESSION['email'];
//Save new password
if(isset($_POST['newpassword']) && isset($_SESSION['email']))
{
$query = "UPDATE users SET password = SHA('$password') WHERE email='" . $email . "'";
$result = mysql_query($query);
if($result)
{
mysql_query("UPDATE tokens SET used=1 WHERE token='" . $token . "'");
}
echo "Your password has been changed successfully";
if(!$result)
{
echo "An error occurred. Please try the again or contact us at [email protected]";
}
}
?>
<table align="center" style="padding-bottom:40px;">
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
<tr>
<td>New Password:</td>
<td><input type="password" name="newpassword" id="password"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Change Password"></td></tr>
<input type="hidden" name="reset" value="TRUE" />
</form>
</table>
請,如果你需要更多的信息或代碼,請不要猶豫,問。
在此先感謝!
從米奇答案應該解決您的問題。如前所述,該功能並不安全,在早期的答案中,它試圖指出[安全密碼重置](http://stackoverflow.com/a/18331345/575765)過程的樣子。 – martinstoeckli
@martinstoeckli - 正如您在Mitch的帖子中發佈的新評論所看到的,他的回答不幸並沒有解決我在使用我的代碼時遇到的問題。 – Fizzix
在第一個獲取請求中,您從數據庫中獲取電子郵件並將其存儲在會話中,然後在第二個發佈請求中從會話中讀取電子郵件。這不是必要的,只有在必要時纔可以閱讀電子郵件(提交表單後)。在你的例子中它不起作用的原因是,你沒有在腳本的開頭調用'session_start()',但是真的,在這裏沒有必要進行會話。 – martinstoeckli