我正在学习PHP,作为一个项目,我开始建立一个社交网络。我确实创建了注册表单和登录表单,我可以将用户添加到我的数据库中。我也哈希他们的密码。这是一个简单的网站,正在进行中,因此存在很多安全漏洞。
我的问题在于登录文件,我似乎无法使用他给我的密码来匹配用户。为了验证用户密码,我使用了password_verify()
功能,但它似乎无法正常工作。
这是我的代码:
注册
<?php
//signUp.php
//Here is where I add a user in my database
//I validate the input, confirm that the password is written like it should be
//check if a user with the same username exists in the database
//if all checks out I will add the user in the database
//and redirect the user to his profile
require_once 'login.php';
require_once 'helperFunctions.php';
$conn = new mysqli($servername, $username, $password, $database);
if(!$conn)
die("Connection failed:" . mysqli_connect_error());
$myUsername = $_POST['Name'];
$myPassword = $_POST['Password'];
$myConfirm = $_POST['conPass'];
sanitize($conn, $myUsername);
sanitize($conn, $myPassword);
//check if the two passwords are the same
if($myPassword != $myConfirm){
print "Your passwords don't match";
header("refresh: 5; index.html");
} else {
//check if username already exists in database
$query = "SELECT * FROM members WHERE Username='$myUsername'";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);
if($count == 0){
//hash password
$hashedPass = password_hash("$myPassword", PASSWORD_DEFAULT);
//username doesn't exist in database
//add user with the hashed password
$query ="INSERT INTO members (Username, Password) VALUES ('{$myUsername}', '{$hashedPass}')";
$result = mysqli_query($conn, $query);
if(!$result)
die("Invalid query: " . mysqli_error());
else{
print "You are now a member or The Social Network";
header("refresh: 5; login_success.php");
}
} else {
print "Username already exists";
header("refresh: 5; index.html");
}
}
?>
登录
<?php
//checkLogin.php
//Here is where I authenticate my users and if successfull I will show them their profile
require_once 'login.php';
require_once 'helperFunctions.php';
$conn = new mysqli($servername, $username, $password, $database);
if(!$conn)
die("Connection failed:" . mysqli_connect_error());
//Values from form
$myUsername = $_POST['Name'];
$myPassword = $_POST['Password'];
//sanitize input
sanitize($conn, $myUsername);
sanitize($conn, $myPassword);
$query = "SELECT * FROM members WHERE Username='$myUsername'";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);
if($count == 1){
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
print "hashedPass = ${row['Password']}";
print "myPassword: " . $myPassword;
if(password_verify($myPassword, $row['Password'])){
print "Password match";
} else
print "The username or password do not match";
}
?>
消毒功能
function sanitize($conn, $val){
$val = stripslashes($val);
$val = mysqli_real_escape_string($conn, $val);
}
通过运行程序print "hashedPass = ${row['Password']}";
打印出哈希密码,该密码与我在数据库中的密码相同但由于某种原因,我在此之后被重定向到print "The username or password do not match";
语句。
答案 0 :(得分:4)
从已删除的答案中删除了评论:
“我记得当我第一次创建数据库时,我使用CHAR(10)作为密码,而散列密码需要更多字符。”
所以这里的全能回答是你的密码栏短50个字符。
password_hash()创建一个60个字符的字符串。
手册指出最好使用VARCHAR,长度为255,以适应未来的变化。
现在的解决方案是重新开始注册,然后使用您目前使用的内容再次登录。
手册中的示例:
<?php
/**
* We just want to hash our password using the current DEFAULT algorithm.
* This is presently BCRYPT, and will produce a 60 character result.
*
* Beware that DEFAULT may change over time, so you would want to prepare
* By allowing your storage to expand past 60 characters (255 would be good)
*/
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
?>
以上示例将输出类似于:
的内容$ 2Y $ 10 $ .vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
同样来自手册:
<强>注意强> 对algo参数使用PASSWORD_BCRYPT将导致密码参数被截断为最大长度为72个字符。
PASSWORD_DEFAULT - 使用bcrypt算法(默认自PHP 5.5.0起)。请注意,此常量旨在随着时间的推移而变化,因为新的和更强大的算法被添加到PHP中。因此,使用此标识符的结果长度可能会随时间而变化。因此,建议将结果存储在数据库列中,该列可以扩展到超过60个字符(255个字符将是一个不错的选择)。
PASSWORD_BCRYPT - 使用CRYPT_BLOWFISH算法创建哈希。这将使用“$ 2y $”标识符生成标准的crypt()兼容哈希。结果将始终为60个字符的字符串,或者在失败时为FALSE 支持的选项:
从删除的答案中删除了另一条评论/问题:
“我可以更改密码字段而无需删除我的表格并从头开始吗?”
答案是肯定的。请参阅堆栈上的Q&amp; A:
您也可以咨询:
旁注:您仍然需要为(旧)受影响的列重新输入新的哈希值。
另外,如前所述;你对SQL注入持开放态度。使用准备好的声明: