因為要做一個帶有會員系統功能,本人需要設置的是用戶注冊如果忘記密碼就需要重設置密碼了,那麼要如何設計密碼重設功能?怎麼做才合理呢,下面我們一起來看看。
用戶流程:
1.用戶忘記密碼,來到密碼重設界面
2.用戶輸入Email地址,點擊重設密碼按鈕
3.用戶收到一封密碼重設郵件,裡面有重設密碼的鏈接,此鏈接有過期時間
4.用戶點擊鏈接,來到密碼重設頁面,輸入新密碼,完成
這個流程並沒有什麼創新,很多網站都是用這套流程
後端實現方式:
1.當用戶輸入Email地址後,驗證這個Email,如果存在於數據庫,那麼取得用戶的user_id
2.將user_id和當前時間戳編碼成HASH,需要提前准備好一個KEY,並且這個KEY只存在服務器上。 HASH = md5 ( user_id + timestamp + KEY )
3.生成一個URL,並且附帶剛剛生成的HASH和用戶id以及timestamp,比如 http://domain.com/reset-password.php?hash=HASH&user_id=123×tamp=1392121211
4.當-三-聯-用戶訪問這個URL, 檢查HASH是否合法: HASH == MD5 ( user_id + timestamp + KEY)
5.檢查 timestamp 是不是過期了
6.如果所有檢查通過,那麼顯示一個新密碼表單給用戶
這種方式的好處:
1.不需要額外的數據表
2.不用擔心參數被用戶惡意修改,因為要檢查hash是不是等於那幾個參數的md5
3.密碼重設URL自帶時間戳
4.只要KEY設置的足夠長足夠復雜,那麼可以認為HASH是絕對安全的
例
send-reset-email.php:
代碼如下 復制代碼
$KEY = "something really long long long long long and secret";
$email = $_POST['email'];
$user = get_user_by_email($email);
if ($user && $user['id'])
{
$time = time();
$hash = md5( $user['id'] . $time . $KEY);
$url = "http://domain.com/reset-password-form.php?id=".$user['id'].'×tamp='.$time.'&hash='.$hash;
send_email($email, 'reset password email from xxx.com', ' Please click the following link to reset password'. $url);
}
reset-password-form.php:
代碼如下 復制代碼
$KEY = "something really long long long long long and secret";
$hash = $_GET['hash'];
$user_id = $_GET['id'];
$timestamp = $_GET['timestamp'];
if ($hash == md5( $user_id . $timestamp . $KEY ))
{
if ( time() - $timestamp > 3600 ) // one hour
{
die('link expired');
}
}
else
{
die('invalid parameters');
}
//validation passed
if ($_POST['new_password'])
{
reset_user_password($user_id, $_POST['new_password']);
die(' password changed successfully ');
}
else
{
echo '
<form action="reset-password-form.php?hash=$hash&id=$user_id×tamp=$timestamp" method="post">
new password: <input type="password" name="new_password">
<input type="submit" value="submit">
</form>
';
}