我正在学习如何在我的简单登录系统中使用预准备语句,以使其更安全。
我已经按照一些不同的教程来使其工作,但无法让它工作。当我输入错误的用户名和密码时,它会给我错误。当我输入用户名和密码正确时,我仍然会收到错误。
我做错了什么?
我是新手,对任何明显的错误表示道歉。
我还调查了哈希密码,因为它目前在数据库中以纯文本形式存储,但这是我完成此工作后的下一步。
这是我的代码:
<?php
error_reporting(E_ALL); ini_set('display_errors', 1);
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
if($SERVER['REQUESTMETHOD'] == 'POST') {
if (empty($POST['username']) || empty($POST['password'])) {
$error = "Enter Username and Password";
}
else
{
// Define $username and $password
$username = $_POST['username'];
$password = $_POST['password'];
//connect to database
include('dbconx.php');
}
$stmt = $con->prepare("SELECT * from admin where password=? AND username=?");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($id, $username, $password);
$stmt->store_result();
if($stmt->num_rows == 1) //To check if the row exists
{
$_SESSION['login_user'] = $username; // Initializing Session
header("location: confirm.php"); // Redirecting To Other Page
}
else {
$error = "Username or Password is incorrect";
}
mysqli_close($con); // Closing Connection
}
?>
答案 0 :(得分:2)
您有向后绑定的参数参数。您的查询会将ALTER PROCEDURE [dbo].[spSearchWord]
@Word nvarchar(100)
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM [testDatabase].[dbo].[User]
WHERE CONTAINS (*, @Word)
END
与password
绑定,但您的username
会使用bind_param()
,然后使用$username
。
我从来不喜欢使用返回的行数来确定存在。相反,您只需使用$password
即可。它将返回一个布尔值,指示是否有结果。
例如
fetch()
答案 1 :(得分:-1)
mysqli_stmt::store_result
之前调用 mysqli_stmt::bind_result
,同时您需要致电mysqli_stmt::seek_data
和mysqli_stmt::fetch
以获取结果。
示例:
<?php
$db = new Mysqli(...);
$inputUsername = $_POST['username'] ?? '';
$inputPassword = $_POST['password'] ?? '';
$statment = $db->prepare('SELECT `id`,`username`,`password` FROM `admin` WHERE `username` = ?');
$statment->bind_param('s',$inputUsername);
$statment->execute();
$statment->store_result();
$statment->bind_result($id,$username,$password);
if($statment->num_rows) {
$statment->data_seek(0);
$statment->fetch();
/**
* this is not secure
* @see http://php.net/manual/en/function.password-hash.php
*/
if($inputPassword === $password) {
echo sprintf('Welcome, %s!',$username);
} else {
echo 'Incorrect password!';
}
} else {
echo sprintf('No such user with the given username (%s)',$inputUsername);
}
$statment->close();
$db->close();
答案 2 :(得分:-1)
为bind_result
和store_result
删除了get_result
和fetch_assoc
。它使得db记录更加灵活和稳定。
重定向后还添加了exit();
,因此重定向命令后不会执行其他代码。
错字:
if (empty($POST['username']) || empty($POST['password']))
$POST
应该是$_POST
。 $error
。即使出现错误,仍会经过mysqli functions
阻止。修复了通过创建包含if statement
块的适当mysqli funtions
的问题。
还为代码添加了适当的缩进以便于阅读。
新代码:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
$_POST['username'] = isset( $_POST['username'] ) ? $_POST['username'] : '';
$_POST['password'] = isset( $_POST['password'] ) ? $_POST['password'] : '';
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if (empty($_POST['username']) || empty($_POST['password'])) {
$error = "Enter Username and Password";
}
else{
// Define $username and $password
$username = $_POST['username'];
$password = $_POST['password'];
//connect to database
include('dbconx.php');
}
if( $error == "" ) {
$stmt = $con->prepare("SELECT * from students where username=? AND password=?");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 1) {
$row = $result->fetch_assoc();
$_SESSION['login_user'] = $row['username']; // Initializing Session
header("location: confirm.php");exit(); // Redirecting To Other Page
}
else {
$error = "Username or Password is incorrect";
}
mysqli_close($con); // Closing Connection
}
echo $error;
}
?>