这个问题更多地与我如何设置简单登录脚本的服务器端代码有关。我对实现目标的最佳方式感兴趣,当然是针对数据库验证用户的用户名和密码,并向他们提供成功登录,注册页面或找到的用户名或密码,但替代方案是错的。
现在,我设置了我的sql查询扫描数据库的用户和传递的位置:
SELECT * FROM test WHERE userName='" + userName + "' AND pass='" + password + "'"
这种方法的问题是要么返回true还是false ...我不知道其中一个输入是否正确而另一个输入是否正确。它要么找到记录,要么找不到记录。
因此,我可以单独根据用户名进行查询,如果找到,则在将用户转到成功登录之前检查记录是否有正确的密码。这样我知道密码是否错误,但我不知道密码是否正确,用户只是输入了错误的用户名。
或者,我可以对此进行扩展,如果找不到用户,则根据密码重新查询数据库,并确定是否可以找到记录但用户名不匹配。这似乎与数据库来回很多,这很好。但我想听听一些专家关于这是否是一种正确的方法。
答案 0 :(得分:1)
我不太了解我的sql是否支持存储过程。如果它受支持,那么您可以像这样制作SP来检查所有情况。下面是MSSQL的代码,你可以用我的sql检查:
IF EXISTS(SELECT [id] FROM [dbo].[users] WHERE [user_name] = @user_name AND [password] = @password)
BEGIN
SELECT 1 AS RETURNVAL --Valid User
END
ELSE IF NOT EXISTS(SELECT [id] FROM [dbo].[users] WHERE [user_name] = @user_name)
BEGIN
SELECT 0 AS RETURNVAL -- User doesn't exist
END
ELSE
BEGIN
SELECT -1 AS RETURNVAL -- Password Not Correct
END
答案 1 :(得分:0)
您不希望向有不良意图的人泄露太多信息,试图探测您的系统是否有可用的用户名(甚至 - 上帝禁止 - 正在使用的密码)。
登录尝试失败时,只需显示一条消息:
用户名和/或密码不匹配。
另外,在使用数据库时,请使用prepared statements,而不是字符串连接;它可以保护您免受SQL注入攻击。 另外 - 虽然您的代码片段并不完全清楚 - 不要存储普通密码或普通密码哈希值。依靠许多可用且经过良好测试的加密/散列库之一,例如PHP's crypt function(确保选择适当的散列函数,例如SHA512)。
您最简单的代码将如下所示:
// coming from your login page
$dbh = new PDO(…);
$sth = $dbh->prepare('SELECT `digest` FROM `users` WHERE `name` = :name LIMIT 1');
$sth->prepare(array( ':name' => $_POST['username'] ));
$result = $sth->fetch();
if($result !== FALSE && crypt($_POST['password'], $result['digest']) === $result['digest']) {
printf('You logged in successfully as %s', htmlspecialchars($_POST['username']));
} else {
echo 'Sorry, username and/or password did not match! Please try again.';
sleep(1);
exit;
}