【发布时间】:2015-02-20 08:02:14
【问题描述】:
好的,所以我正在我网站的这个更改密码部分编码。
请注意,我才刚接触 PHP 几个星期。
这就是为什么我之前使用 md5 进行密码加密,但我研究了密码安全性并决定使用 PHP 的 crypt() 函数来散列我的密码,而不仅仅是 md5 左右。
我之前的更改密码功能遇到了一个问题,在将新密码保存到数据库后导致用户被注销后,用户会话被中止。旧密码修改站点供参考:http://pastebin.com/hf6WhtEQ
我最初的方法是使用session_regenerate_id() 来更新会话,因为似乎简单地更新 cookie 中的密码是行不通的。
这种方法起初似乎有效,但经过进一步测试,很明显它没有用。
所以我从头开始并创建了以下代码。
我还没有实现 cookie,因为我仍然不确定如何去做,并希望在设置新的 cookie 之前先确保我有强大的密码安全性。
现在我的计划是这样的:
我检查用户是否已登录以及帐户的所有者。
我想检查数据库中的密码是否与
$oldpass中的密码匹配。我想比较
$newpass和$repeatpass,如果两个密码匹配,那么我想使用crypt()加密$newpass。最后,我想用新的加密密码更新数据库,并用新的密码更新 cookie,同时确保用户保持登录状态。
现在,我的问题是:
为什么我一直收到消息“该用户不存在或尚未激活,请按回”,即使标题中明确包含用户名。
我怎样才能以井井有条的方式将一切都按照我的计划执行。 (现在它是无序的,我不确定 if 语句等的正确顺序应该是什么)。
change_pass.php:
<?php
include 'check_login_status.php';
$u="";
$oldpass=md5("");
//stripping both strings of white spaces
$newpass = preg_replace('#[^a-z0-9]#i', '', $_POST['newpass']);
$repeatpass = preg_replace('#[^a-z0-9]#i', '', $_POST['repeatpass']);
//get the username from the header
if(isset($_GET["u"])){
$u = preg_replace('#[^a-z0-9]#i', '', $_GET['u']);
} else {
header("location: compare_pass.php?u=".$_SESSION["username"]);
exit();
}
// Select the member from the users table
$sql = "SELECT * FROM users WHERE username='$u' AND password='$oldpass' LIMIT 1";
$user_query = mysqli_query($db_conx, $sql);
// Now make sure that user exists in the table
$numrows = mysqli_num_rows($user_query);
if($numrows < 1){
echo "That user does not exist or is not yet activated, press back";
exit();
}
$isOwner = "no";
//check if user is logged in owner of account
if($u == $log_username && $user_ok == true){
$isOwner = "yes";
}
$passhash = "";
if (($newpass) === ($repeatpass)) {
$passhash = crypt_sha256("$newpass", "B-Pz=0%5mI~SAOcW0pMUdgKQh1_B7H6sbKAl+9~O98E9MBPrpGOtE65ro~8R");
} else {
echo "comparison failed! :(";
}
//
if (isset($_POST["submit"]) &&($isOwner == "yes") &&($user_ok == true) &&($newpass) === ($repeatpass)) {
$sql = "UPDATE users SET `password`='$passhash' WHERE username='$u' LIMIT 1";
}
?>
<h3>Create new password</h3>
<form action="" method="post">
<div>Current Password</div>
<input type="text" class="form-control" id="password" name="oldpass" >
<div>New Password</div>
<input type="text" class="form-control" id="password" name="newpass" >
<div>Repeat Password</div>
<input type="text" class="form-control" id="password" name="repeatpass" >
<br /><br />
<input type="submit" name="submit" value="Submit">
<p id="status" ></p>
</form>
check_login_status.php:
<?php
session_start();
include_once("db_conx.php");
// Files that inculde this file at the very top would NOT require
// connection to database or session_start(), be careful.
// Initialize some vars
$user_ok = false;
$log_id = "";
$log_username = "";
$log_password = "";
// User Verify function
function evalLoggedUser($conx,$id,$u,$p){
$sql = "SELECT ip FROM users WHERE id='$id' AND username='$u' AND password='$p' AND activated='1' LIMIT 1";
$query = mysqli_query($conx, $sql);
$numrows = mysqli_num_rows($query);
if($numrows > 0){
return true;
}
}
if(isset($_SESSION["userid"]) && isset($_SESSION["username"]) && isset($_SESSION["password"])) {
$log_id = preg_replace('#[^0-9]#', '', $_SESSION['userid']);
$log_username = preg_replace('#[^a-z0-9]#i', '', $_SESSION['username']);
$log_password = preg_replace('#[^a-z0-9]#i', '', $_SESSION['password']);
// Verify the user
$user_ok = evalLoggedUser($db_conx,$log_id,$log_username,$log_password);
} else if(isset($_COOKIE["id"]) && isset($_COOKIE["user"]) && isset($_COOKIE["pass"])){
$_SESSION['userid'] = preg_replace('#[^0-9]#', '', $_COOKIE['id']);
$_SESSION['username'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['user']);
$_SESSION['password'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['pass']);
$log_id = $_SESSION['userid'];
$log_username = $_SESSION['username'];
$log_password = $_SESSION['password'];
// Verify the user
$user_ok = evalLoggedUser($db_conx,$log_id,$log_username,$log_password);
if($user_ok == true){
// Update their lastlogin datetime field
$sql = "UPDATE users SET lastlogin=now() WHERE id='$log_id' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
}
}
?>
【问题讨论】:
-
如果你把这个问题稍微精简一点,每个人都会真正受益。您正在就三个充满代码的屏幕提出四个不同的问题,其中的序言似乎大多无关紧要且难以理解。这种方式很难得到有用的答案。如果有的话,一次问一个问题。
-
是的,确实如此,需要回答的输入很多,我只是认为最好将所有内容都包含在一篇文章中,而不是将所有内容分开并冒着因问太多问题而受到惩罚的风险。