如何检查用户是否输入了正确的密码才能登录?
这就是我所做的(在一堆组合......中):
<?
$login = $_POST['login'];
$password = $_POST['password'];
mysql_connect('localhost', 'root', 'abc123');
mysql_select_db('aun_vox') or die(mysql_error());
$q = mysql_query("SELECT password FROM customer WHERE login='$login'");
$db_pass = mysql_result($q, 0);
if(md5($password) == $db_pass)
{
echo "You did it.";
}
else echo "Wrong.";
?>
正如我从输出中看到的那样,mysql_result
位出现了问题,但我无法找到正确的方法。
有人可以帮忙。
答案 0 :(得分:17)
我看到您在数据库中存储了密码的哈希值,但为了其他读者的利益,从不以纯文本形式存储数据库中的密码。你不想成为like Monster.com.uk!
您应该使用比MD5()
更强的散列函数。理想情况下,您应该使用SHA256。使用hash()
函数在PHP中可以使用此哈希方法。
您还应该随机salt应用于密码。为每个用户的帐户存储不同的盐值。这有助于打败字典攻击和rainbow table攻击。
您应该学习使用mysqli扩展名而不是旧的mysql扩展名。 Mysqli支持参数化查询,因此您可以减少一些SQL注入攻击的漏洞。
以下是一些示例代码。我没有测试过,但它应该非常接近工作:
$input_login = $_POST['login'];
$input_password = $_POST['password'];
$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);
while ($stmt->fetch()) {
$input_password_hash = hash('sha256', $input_password . $salt);
if ($input_password_hash == $password_hash) {
return true;
}
// You may want to log failed password attempts here,
// for security auditing or to lock an account with
// too many attempts within a short time.
}
$stmt->close();
// No rows matched $input_login, or else password did not match
return false;
其他人建议查询应该测试login = ? AND password = ?
,但我不喜欢这样做。如果这样做,您无法知道查找是否因为登录不存在而失败,或者因为用户提供了错误的密码。
当然,您不应向用户透露导致登录失败的原因,但您可能需要知道,因此您可以记录可疑活动。
@Javier在他的回答中说你不应该从数据库中检索密码(或者在这种情况下是密码哈希)。我不同意。
Javier显示在PHP代码中调用md5()
并将生成的哈希字符串发送到数据库。但这并不支持轻松保存密码。您必须先执行单独的查询以检索此用户的salt,然后才能在PHP中执行哈希。
另一种方法是通过网络从您的PHP应用程序向数据库服务器发送明文密码。任何窃听您网络的人都可以看到此密码。如果您记录了SQL查询,那么获得日志访问权限的任何人都可以看到密码。有动力的黑客甚至可以通过垃圾站潜水查找旧的文件系统备份媒体,并可能以这种方式读取日志文件!
较小的风险是从数据库中将密码哈希字符串提取到PHP应用程序中,将其与用户输入的哈希值(也在PHP代码中)进行比较,然后丢弃这些变量。
答案 1 :(得分:2)
首先,确保在查询中使用它们之前正确转义变量 - 使用mysql_real_escape_string()。
那么,为什么不使用MySQL MD5函数来检查查询中的有效登录?
SELECT login FROM customer WHERE login='$login' AND password = MD5('$password')
然后只使用mysql_num_rows()来计算返回的行数。
答案 2 :(得分:1)
一些观点:
我通常做的是:
$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?");
bindvalue ($q, $_POST['login']);
bindvalue ($q, md5($_POST['password']));
$id = execprepared ($q);
if($id) {
echo "You did it.";
} else {
echo "Wrong.";
}
答案 3 :(得分:0)
从FORM POST方法获取用户密码并将$ _POST ['password'] //从表单//转换为适当格式的php / jsp / any,然后与数据库中的格式化密码进行比较
通常使用md5加密,您可以比较md45('{$ _ POST ['password']}')=存在于您的数据库中; 或者通常mysql在创建密码时使用密码('你的密码')命令,因此首先将你的$ _POST ['密码']与mysqli_query和mysqli_fetch_array进行对比,以获得加密的密码值,然后进行比较。
答案 4 :(得分:0)
大于PHP 5.6,您可以使用hash_compare函数。
$users_password = hash(sha256,$salt.$post_password);
if (hash_equals($users_dbpassword, $users_password)) {
//pass is good
} else {
// pass failed
}