使用准备好的语句登录系统 mysqli
Login system with prepared statements mysqli
我正在努力将我的登录系统转换为准备好的语句。我已经设法转换了我的整个 Crud 系统,但只是对最后一部分感到困惑。任何帮助将不胜感激。
这是没有准备语句的原始登录:
if(isset($_POST['submit'])) {
$user = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);
if($user == "" || $password == "") {
echo "Either username or password field is empty.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
} else {
$result = mysqli_query($con, "SELECT * FROM login WHERE username='$user' AND password=md5('$password')")
or die("Could not execute the select query.");
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
} else {
?>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="box">
<h3>Login</h3>
<form name="form1" action="" method="POST" enctype="multipart/form-data">
<input type="text" name="username" id="username" placeholder="Username" class="form-control"><br>
<input type="password" name="password" id="password" placeholder="Password" class="form-control"><br>
<button type="submit" name="submit" class="btn btn-success button">Login</button>
</form>
</div>
</div>
<?php
}
?>
</body>
</html>
然后是我的 index.php 页面
<?php
if(isset($_SESSION['valid'])) {
include("connect.php");
$result = mysqli_query($con, "SELECT * FROM login");
?>
Welcome <?php echo $_SESSION['name'] ?> ! <a href='logout.php'>Logout</a><br/>
<br/>
<a href='view.php'><?php echo ("<div class='alert alert-success'>Click here to View and Add Products!</div>")?></a>
<a href='viewuser.php'><?php echo ("<div class='alert alert-success'>Click here to Add Users!</div>")?></a>
<br/><br/>
<?php
} else {
echo ("<div class='alert alert-danger'>You must be logged in to access CMS site.</div>");
echo "<a href='login.php' class='btn btn-primary'>Login</a>";
}
?>
这是我目前所做的:
if(isset($_POST['submit'])) {
$user = $_POST['username'];
$password = md5(['password']);
$sql = $con->prepare("SELECT * FROM login WHERE username = ? AND password = ?");
$sql->bind_param("ss", $user, $password);
$sql->execute();
$result = $sql->get_result();
while($row = $result->fetch_assoc()) {
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
}
?>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="box">
<h3>Login</h3>
<form name="form1" action="" method="POST" enctype="multipart/form-data">
<input type="text" name="username" id="username" placeholder="Username" class="form-control"><br>
<input type="password" name="password" id="password" placeholder="Password" class="form-control"><br>
<button type="submit" name="submit" class="btn btn-success button">Login</button>
</form>
</div>
</div>
</body>
</html>
在这一部分,我对如何使用 index.php 在准备好的语句中实现它感到非常困惑
无论我尝试通过互联网搜索什么,我似乎都无法弄清楚这部分:
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
}
正如评论已经指出的那样,应该使用像 password_hash() 这样的适当函数,并将散列存储在 varchar(255)
:
类型的字段中
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
在登录表单中,我们无法直接使用SQL验证密码,也无法搜索密码,因为存储的哈希值是经过加盐处理的,计算单个哈希值非常耗时。相反,我们...
- 必须从数据库中读取密码哈希,通过用户 id 搜索
- 之后可以使用 password_verify() 函数根据找到的哈希值检查登录密码。
您可以在下面找到 mysqli 的代码示例,显示如何使用 mysqli 连接进行密码验证。该代码没有错误检查以使其可读:
/**
* mysqli example for a login with a stored password-hash
*/
$mysqli = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
$mysqli->set_charset('utf8');
// Find the stored password hash in the db, searching by username or email
$sql = 'SELECT password FROM users WHERE username = ?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('s', $_POST['username']); // it is safe to pass the user input unescaped
$stmt->execute();
// If this user exists, fetch the password-hash and check it
$isPasswordCorrect = false;
$stmt->bind_result($hashFromDb);
if ($stmt->fetch() === true)
{
// Check whether the entered password matches the stored hash.
// The salt and the cost factor will be extracted from $hashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $hashFromDb);
}
我正在努力将我的登录系统转换为准备好的语句。我已经设法转换了我的整个 Crud 系统,但只是对最后一部分感到困惑。任何帮助将不胜感激。
这是没有准备语句的原始登录:
if(isset($_POST['submit'])) {
$user = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);
if($user == "" || $password == "") {
echo "Either username or password field is empty.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
} else {
$result = mysqli_query($con, "SELECT * FROM login WHERE username='$user' AND password=md5('$password')")
or die("Could not execute the select query.");
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
} else {
?>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="box">
<h3>Login</h3>
<form name="form1" action="" method="POST" enctype="multipart/form-data">
<input type="text" name="username" id="username" placeholder="Username" class="form-control"><br>
<input type="password" name="password" id="password" placeholder="Password" class="form-control"><br>
<button type="submit" name="submit" class="btn btn-success button">Login</button>
</form>
</div>
</div>
<?php
}
?>
</body>
</html>
然后是我的 index.php 页面
<?php
if(isset($_SESSION['valid'])) {
include("connect.php");
$result = mysqli_query($con, "SELECT * FROM login");
?>
Welcome <?php echo $_SESSION['name'] ?> ! <a href='logout.php'>Logout</a><br/>
<br/>
<a href='view.php'><?php echo ("<div class='alert alert-success'>Click here to View and Add Products!</div>")?></a>
<a href='viewuser.php'><?php echo ("<div class='alert alert-success'>Click here to Add Users!</div>")?></a>
<br/><br/>
<?php
} else {
echo ("<div class='alert alert-danger'>You must be logged in to access CMS site.</div>");
echo "<a href='login.php' class='btn btn-primary'>Login</a>";
}
?>
这是我目前所做的:
if(isset($_POST['submit'])) {
$user = $_POST['username'];
$password = md5(['password']);
$sql = $con->prepare("SELECT * FROM login WHERE username = ? AND password = ?");
$sql->bind_param("ss", $user, $password);
$sql->execute();
$result = $sql->get_result();
while($row = $result->fetch_assoc()) {
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
}
?>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="box">
<h3>Login</h3>
<form name="form1" action="" method="POST" enctype="multipart/form-data">
<input type="text" name="username" id="username" placeholder="Username" class="form-control"><br>
<input type="password" name="password" id="password" placeholder="Password" class="form-control"><br>
<button type="submit" name="submit" class="btn btn-success button">Login</button>
</form>
</div>
</div>
</body>
</html>
在这一部分,我对如何使用 index.php 在准备好的语句中实现它感到非常困惑 无论我尝试通过互联网搜索什么,我似乎都无法弄清楚这部分:
$row = mysqli_fetch_assoc($result);
if(is_array($row) && !empty($row)) {
$validuser = $row['username'];
$_SESSION['valid'] = $validuser;
$_SESSION['name'] = $row['name'];
$_SESSION['id'] = $row['id'];
} else {
echo "Invalid username or password.";
echo "<br/>";
echo "<a href='login.php'>Go back</a>";
}
if(isset($_SESSION['valid'])) {
header('Location: index.php');
}
}
}
正如评论已经指出的那样,应该使用像 password_hash() 这样的适当函数,并将散列存储在 varchar(255)
:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
在登录表单中,我们无法直接使用SQL验证密码,也无法搜索密码,因为存储的哈希值是经过加盐处理的,计算单个哈希值非常耗时。相反,我们...
- 必须从数据库中读取密码哈希,通过用户 id 搜索
- 之后可以使用 password_verify() 函数根据找到的哈希值检查登录密码。
您可以在下面找到 mysqli 的代码示例,显示如何使用 mysqli 连接进行密码验证。该代码没有错误检查以使其可读:
/**
* mysqli example for a login with a stored password-hash
*/
$mysqli = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
$mysqli->set_charset('utf8');
// Find the stored password hash in the db, searching by username or email
$sql = 'SELECT password FROM users WHERE username = ?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('s', $_POST['username']); // it is safe to pass the user input unescaped
$stmt->execute();
// If this user exists, fetch the password-hash and check it
$isPasswordCorrect = false;
$stmt->bind_result($hashFromDb);
if ($stmt->fetch() === true)
{
// Check whether the entered password matches the stored hash.
// The salt and the cost factor will be extracted from $hashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $hashFromDb);
}