如何检查用户名和密码是否与数据库值匹配
如果问题看起来很愚蠢,我真的很抱歉。但是,我一直试图几天来检查我username
和password
数据库匹配我在html
页我打字......这是我的登录表单...如何检查用户名和密码是否与数据库值匹配
<form method="POST" action="Dashboard/Dashboard.php">
<div class="form-group md-form">
<!--<input type="email" class="form-control" id="email" value="" placeholder="Enter email address">-->
<i class="fa fa-user prefix grey-text"></i>
<input name="username" id="username" type="text" class="form-control" required>
<label for="defaultForm-email">Username</label>
</div>
<div class="form-group md-form">
<!--<input type="password" class="form-control" id="password" value="" placeholder="Enter password">-->
<i class="fa fa-lock prefix grey-text"></i>
<input name="password" id="password" type="password" class="form-control" required>
<label for="defaultForm-pass">Your password</label>
</div>
<div class="text-center">
<button type="reset" class="btn btn-amber btn-sm"><strong>Reset</strong></button>
<input type="submit" name="submit" id="submit" class="btn btn-green btn-sm" value="Sign in">
</div>
</form>
这是代码(php
)我使用的Dashboard.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$databaseName = "test";
$conn = mysqli_connect($servername, $username, $password, $databaseName);
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
$result_can = mysqli_query($conn, $query);
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
?>
我真的试过像几千倍,但无法弄清楚我哪里错了...任何人都可以帮我吗?
我知道我的代码是开放给SQL注入的,但我不在乎它,因为这是我需要向我的朋友展示的一个示例因此忽视该部分。
堆栈溢出是 “专业和发烧级的程序员。”尊敬的你已经向我们展示了你的问题中的代码,它甚至不值得任何名称。
StackOverflow人对幽默安全代码没有多少幽默感。你会对你的代码产生强烈的反应,因为Equifax,Ashley Madison和Adobe以及网络犯罪分子破解的所有其他地方。为什么我们跳上你?因为我们不喜欢网络罪犯,我们不想让他们的生活变得轻松。朋友不要让朋友做坏密码安全。朋友不会向朋友展示严重不安全的密码验证代码。
你的代码有什么问题?您将密码存储为纯文本,并且您很容易受到SQL注入攻击。我将解决第一个问题。
幸运的是,php有很好的密码安全设施。在这里阅读有关它们。 http://php.net/manual/en/faq.passwords.php使用它们。你如何处理密码?
- 当用户在您的网站上注册并首次提供密码时,您会对其进行哈希处理,如下所示。
$usersPassword = $_POST['password']);
$hash = password_hash($usersPassword , PASSWORD_DEFAULT);
// you then store the username and the hash in your dbms.
// the column holding the hash should be VARCHAR(255) for future-proofing
// NEVER! store the plain text (unhashed) password in your database
-
当用户尝试登录,你做这样的查询:
SELECT log_password FROM log_user WHERE log_username = TheUsernameGiven
然后你把检索到的密码进入一列名为
$hash
。然后,您使用php's
password_verify()
function来检查您的可能用户刚刚给您的密码是否与数据库中的密码相符。最后,您检查用户的密码是否需要重新设置,因为之前用于哈希的方法已过时。
$usersPassword = $_POST['password']);
$valid = password_verify ($usersPassword, $hash);
if ($valid) {
if (password_needs_rehash ($hash, PASSWORD_DEFAULT)) {
$newHash = password_hash($usersPassword, PASSWORD_DEFAULT);
/* UPDATE the user's row in `log_user` to store $newHash */
}
/* log the user in, have fun! */
}
else {
/* tell the would-be user the username/password combo is invalid */
}
这个序列是面向未来的,因为它可以在以后老调重弹的密码,如果旧的哈希方法获取太容易了cybercreeps破解。
非常感谢您先生:)这工作! – user8794865
这里有几个问题,无论是在你的代码还是在思考过程中。让我们以自己的方式下:
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
这print
线应该可以给你一个警告。变量$pass
和$email
不存在。您应该删除该行,除非您尝试要做的是要打印$un
和$pw
。
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
没有必要同时选择用户名和密码列。如果有匹配,它们将始终与您已拥有的$un
和$pw
相同。您只是检查用户名和密码是否正确,因此选择单个列就足够了。最好是用户名,但只有用户名就足够了。请注意,假设查询成功执行,$query
将包含一个mysqli_result
对象。
$result_can = mysqli_query($conn, $query);
此行需要删除。你已经执行了你的查询,并且$query
是它的结果,你在这里做的没有意义,应该给你一个警告,或者甚至是一个致命的错误。
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
您不能混合mysql_*
和mysqli_*
功能。在这里使用mysql_fetch_assoc()
应该会给你一个致命的错误。您应该使用mysqli_fetch_assoc()
来代替(在$query
而不是$result_can
),但是:
,因为你只在是否有任何结果在所有感兴趣,这整段可以改成:
if (mysqli_num_rows($query) > 0) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
这会带来其他问题,因为您不能使用header()
在回显您的<script>
标记后重定向用户(您将收到“头文件已发送”错误)。如果您想要JavaScript警报,请使用Javascript执行重定向。同样,$message
变量是没有用处,还不如直接把消息进入警戒状态:
if (mysqli_num_rows($query) > 0) {
echo "<script type='text/javascript'>alert('ok'); window.location.href='Doctors.php';</script>";
} else {
echo "<script type='text/javascript'>alert('No'); window.location.href='Doctors.php';</script>";
}
一旦你解决这些问题都,你仍然有一些思考的事情。
- 您应该从不在数据库中以纯文本格式存储密码。
- 您可能不关心SQL注入的权利,但与当前查询我可以通过输入自己的用户名作为
admin' AND 1 --
任何有效的用户(例如,“管理员”)登录,或者如果我只是想获得我可以使用一个用户名的any' OR 1 --
,并作为表中的第一个用户登录。查看准备好的陈述以及它们的工作方式。 - 你有没有错误处理的。您应该添加检查以查看数据库连接是否已成功打开,查询是否正确执行,表单是否已发布以及用户名/密码字段是否已填写,并考虑如何向用户显示有用的错误消息。
这里的主要教训应该是:当您开发并且无法正常工作时,请始终检查错误日志以查看它是否包含任何提示并打开PHP的错误报告功能,以便您可以看到您在你的浏览器中做错了。
非常感谢您的先生:) – user8794865
几个问题,有的被评论上述。
混合mysql_ *与mysqli_ * API
与您通话mysqli_query()
查询,但你尝试用mysql_fetch_assoc()
获取结果。你不能混用这些不同的API。 mysql_*
函数不会使用您使用mysqli_connect()
打开的连接,反之亦然。选择一个MySQL扩展并坚持下去。
提示:不要使用mysql_*
在所有。它的过时,已经从PHP 7.0+
与都用户名和密码
只要搜索的用户名,并获取密码查询条件删除。如果搜索均为,那么搜索将返回零行,除非使用了正确的密码。
你不希望出现这种情况。您希望避免将明文密码放入SQL查询中。只需搜索用户名,并获取存储的密码,然后比较您获取的用户输入密码。
未初始化变量
如果您从您的查询取零行,然后$check_username
和$check_password
永远不会置。然后你比较你的if语句中的那些变量。不是一个致命的错误,但风格不好。
无密码散列
你似乎是比较用户输入的,我以为是明文的,直接到什么是存储在数据库中。 You're Probably Storing Passwords Incorrectly.
相反,当你存储你的密码,先用password_hash()。
没有查询参数
我知道你说你不关心你的SQL注入漏洞,但这就像是一名电工,说你不关心您的电气面板塞满了含油抹布。请务必在LinkedIn个人资料中张贴您对安全的漠视,让雇主知道应该避免哪些问题。
推荐实施
mysqli_report(MYSQLI_REPORT_STRICT); // enable exceptions
$conn = new mysqli($servername, $mysql_username, $mysql_password, $databaseName);
$log_username = $_POST['username'];
$log_password = $_POST['password'];
$sql = "SELECT log_username, log_password_hash FROM login WHERE log_username=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $log_username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
if (password_verify($log_password, $row['log_password_hash'])) {
$message = "ok";
// header must be called before any other output
header("Location: Doctors.php");
exit();
}
}
$message = "No";
// header must be called before any other output
header("Location: Doctors.php");
非常感谢您先生... – user8794865
“*我知道我的代码对SQL注入是开放的,但我不在乎*”。一些有史以来最危险的词:) –
为什么要向你的朋友展示一个没有人应该做的事情的例子?向他们展示如何从一开始就正确地做到这一点。另外,你还没有真正说明你实际上*有什么问题。 – Sammitch
https:// stackoverflow。com/help/mcve – Sammitch