注册表格一切正常,但我无法弄清楚如何填写登录表格。我搜索了很多,但没有运气,我是PHP的新手。请给我提示和解决方案。
if (isset($_POST['username']) && isset($_POST['password']))
{
$username = $_POST['username'];
$_SESSION['LoggedIn'] = $username; //store username in session
$password = $_POST['password'];
// To protect MySQL injection (more detail about MySQL injection)
$username = stripslashes($username);
$password = stripslashes($password);
// $username = mysql_real_escape_string($username);
// $password = mysql_real_escape_string($password);
$hash_password = password_hash($password , PASSWORD_DEFAULT);
$verify_password = password_verify($_POST['password'] , $hash_password);
// check login errors
$check_login_errors = LoginErrors($username , $password);
if ($check_login_errors)
{
//search database
$query = "SELECT * FROM users WHERE Username='$username' AND Password='$hash_password'";
$query_result = mysqli_query($connection , $query);
//check database for username
if (mysqli_fetch_array($query_result,MYSQLI_NUM > 0))
{
//verify password and username
if($verify_password == $username)
{
echo "logged in";
$_SESSION['LoggedIn'];
RedirectTo("profile.php");
}
else
{
echo "wrong password or username";
}
}
else
{
echo "error with checking username in database";
}
}
}
?>
我尝试的一切都给了我最后一个错误:
检查数据库中的用户名时出现错误
注意我在PHP代码的顶部添加了session_start()
。
答案 0 :(得分:3)
我相信你没有在这里正确使用password_verify
- 散列密码已经存在于数据库中(大概是散列的重点是什么?)所以你需要将该值与发布的密码进行比较。我修改了代码以使用预处理语句,因为原始代码可能仍然容易受到SQL注入攻击。
此外,在散列/验证密码之前使用stripslashes
会在某些情况下破坏密码。例如,这会阻止包含反斜杠(\
)的密码起作用,这是一个完全合法的密码。
if( isset( $_POST['username'], $_POST['password'] ) ){
$username = $_POST['username'];
$password = $_POST['password'];
$stmt=$connection->prepare(
'select `username`,`password` from `users` where `username`=?'
);
if( $stmt ){
$stmt->bind_param( 's', $username );
$result = $stmt->execute();
if( $result ){
$stmt->store_result();
$stmt->bind_result( $uname,$upwd );
$stmt->fetch();
$stmt->free_result();
$stmt->close();
/* compare POSTed password and HASH from db */
$verify = password_verify( $password, $upwd );
if( $verify ){
$_SESSION['LoggedIn'] = $username;
header('Location: profile.php' );
} else {
/* more bad foo */
echo "wrong password or username";
}
} else {
echo "bad foo: error with checking username in database";
}
} else {
echo "Failed to prepare sql query";
}
}
-
准备好的声明执行包括两个阶段:准备和 执行。在准备阶段,语句模板被发送到 数据库服务器服务器执行语法检查并初始化 服务器内部资源供以后使用。
准备之后是执行。在执行期间,客户端绑定 参数值并将它们发送到服务器。服务器创建一个 语句模板中的语句和要执行的绑定值 它使用以前创建的内部资源。
所以,要打破它:
$sql='select `username`,`password` from `users` where `username`=?';
sql语句提取两列,但实际上只需要密码。请注意?
的使用 - 这是我们将变量绑定到的占位符 - 在本例中为$username
。如果prepare
方法失败,它将返回false,因此我们可以将其用作逻辑测试来继续或拯救。
$stmt->prepare( $sql );
准备SQL查询,并返回一个语句句柄,用于对语句进行进一步操作。查询必须包含单个SQL语句。
[ Read more about $stmt->prepare() ]
$stmt->bind_param( 's', $username );
此时必须已成功准备语句,因此我们将$username
变量绑定到占位符。由于用户名是字符串,我们使用s
作为类型。
可能有四种类型,它们如下:
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
[ Read more about $stmt->bind_param() ]
$result = $stmt->execute();
现在语句已准备好并且所有变量都绑定到它们的占位符,提交查询并使用响应进行进一步的逻辑测试,因为这会在成功时返回TRUE,否则返回FALSE。
[ Read more about $stmt->execute() ]
$stmt->store_result();
使我们能够使用返回的记录集
[ Read more about $stmt->store_result() ]
$stmt->bind_result( $uname,$upwd );
将变量绑定到结果存储的预准备语句。当查询获取两列时,我们绑定两个变量 - 它们在此阶段不存在,但在我们fetch
实际记录集时将变为可用。
[ Read more about $stmt->bind_result() ]
$stmt->fetch();
将准备好的语句中的结果提取到绑定变量中。这使$uname
& $upwd
可用作变量,但我们希望(在合理范围内)
[ Read more about $stmt->fetch() ]
答案 1 :(得分:0)
如果条件如下,你在下面犯了一个小错误: -
if (mysqli_fetch_array($query_result,MYSQLI_NUM > 0))
请改用:
if (mysqli_fetch_array($query_result,MYSQLI_NUM) > 0)
语法: - mysqli_fetch_array(result,resulttype);
答案 2 :(得分:0)
为了理智,可以在接受的答案中使用现实版本的代码。当然,你不打算编写一个代码来运行一个单独的查询,是吗?
if( isset( $_POST['username'], $_POST['password'] ) ){
$sql = 'select `username`,`password` from `users` where `username`=?';
$stmt = $connection->prepare($sql);
$stmt->bind_param( 's', $_POST['username'] );
$stmt->execute();
$stmt->bind_result( $uname,$upwd );
if ($stmt->fetch() && password_verify( $_POST['password'], $upwd );
$_SESSION['LoggedIn'] = $username;
header('Location: profile.php' );
exit;
}
echo "wrong password or username";
}