prepare函数无法识别DB中已存在的成员,因此,当它应该通过else语句时,总是调用函数NewUser()?我相信这是因为当我要求它验证密码时,会遇到错误,但我不知道我做错了什么?
function NewUser(){
global $dbh;
$fullname = trim($_POST['fullname']); //at a minimus clear whitespace.
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$user_password = trim($_POST['password']);
$options = [
'cost' => 12, //higher = more lower= less. you want it to take around 0.4 seconds for security reasons!
];
$hashed_password = password_hash($user_password, PASSWORD_DEFAULT, $options); // hashed password for storage!
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password) VALUES('$fullname', '$username', '$email', '$hashed_password')");
$stmt->bindValue(1,$fullname,PDO::PARAM_STR);
$stmt->bindValue(2,$username,PDO::PARAM_STR);
$stmt->bindValue(3,$email,PDO::PARAM_STR);
$stmt->bindValue(4,$user_password,PDO::PARAM_STR);
if($stmt->execute()){
echo "<div class= container>","<div class = \" col-md-2 connout slideInTop\">"," <span class = \"username_text\">$username</span>, <br> welcome to <br> the <br> <span class = \"vibecourt_text\">VIBECOURT</span> family! <br><br> You may <br> now sign in <br> below","</div>","</div>";
}
}
function SignUp(){
global $dbh;
//checking the 'user' name which is from index.php, is it empty or have some text
if(!empty($_POST['username'])){
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
//check password agaisnt stored hash
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
else{
echo("<script>location.href = 'pages/home/home.php'</script>");
}
}
}
SignUp();
答案 0 :(得分:0)
更新了答案
根据评论中发生的情况......似乎问题远远超出了您最初将散列密码存储到数据库中的位置。
您说您使用varchar(50)
代表password_hash
值。这太短了,mysql毫无疑问会削减INSERT
。这将导致无法匹配的哈希值。
您应该至少有varchar(60)
,但PHP.net声明此哈希值会随着时间的推移而增长,建议使用varchar(255)
。
在这一点:
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
您正尝试使用用户输入的密码(未经过哈希处理)来匹配数据库中的哈希值。
您只需删除AND password = ?
和bindValue
即可。这样它从数据库中提取匹配的用户名条目,然后然后password_verify
确定用户输入的密码是否匹配:
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE username = ?");
$stmt->bindValue(1, $username, PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
附注:虽然我不确定你是否真的想要新用户,如果他们只是输入了错误的密码???当然你会以不同的方式处理。告诉他们他们输入了错误的密码,应该再试一次。
修改强>
同样在你的NewUser功能中你有这个:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES('$fullname', '$username', '$email', '$hashed_password')");
应该是这样的:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES(?, ?, ?, ?)");
// ...
$stmt->bindValue(4,$hashed_password,PDO::PARAM_STR);// <- use $hashed_password