0

例如,有人尝试使用名称“Bob”登录,但数据库中没有 Bob。是否应该通知用户没有 Bob,或者程序是否应该简单地说“身份验证失败”(我注意到 Gmail 会这样做)?这部分是可用性问题,部分是效率问题。现在程序查询数据库以查看给定的用户名是否存在,如果存在,则再次查询数据库以查找相同用户名的密码哈希(冗余)。

//$link is the link to the database storing passwords/usernames
if(userNameExists($uName, $link))
{
    if(passwordCorrect($uName, $pass, $link))
        echo 'log in successful!';
    else
        echo 'can\'t log in';
}
else
{
    echo 'username doesn\'t exist!';
}

/*This function checks to see if the username exists
INPUT: the userName to check for and a link to the database
OUTPUT: true if username exists
*/
function userNameExists($userName, $link)
{
    $result = mysqli_query($link, 'SELECT `userid`
                        FROM `login`
                        WHERE `userid` = \''.$userName.'\' LIMIT 1');//need to look into uses of backticks, single quotes, double quotes
    return mysqli_num_rows($result) == 1;
}

/*This function checks the password for a given username
INPUT: the userName and password the user entered, and a link to the database
OUTPUT: true if the given password matches the one in the database
*/
function passwordCorrect($userName, $givenPassword, $link)
{
    $result = mysqli_query($link, 'SELECT `password`
                        FROM `login`
                        WHERE userid = \''.$userName.'\' LIMIT 1');
    $retrievedPassword = mysqli_fetch_array($result);
    if(password_verify($givenPassword, $retrievedPassword['password']))
        return true;
    else
        return false;
}

我应该只使用passwordCorrect()并且如果mysqli_query()返回 false 这意味着用户名不存在(诚然我不喜欢这些解决方案,因为这可能意味着其他地方出了问题,不是吗?)?

4

2 回答 2

2

您不应提供登录失败的详细信息(用户不存在或密码错误),因为这会增加安全性。除非在未登录时用户名可见(这实际上是不安全的,不应该是这种情况..!)

优点是您确实可以使用单个查询来获取给定用户名的哈希值。如果没有得到结果,说明用户名错误(登录失败),否则可以(直接)检查哈希(查看密码是否错误)。

于 2013-01-21T22:31:53.850 回答
1

粗略地说,您可以考虑这个故事的两个基本点

  1. 提供特定信息可以提高可用性,因为用户知道他提供的哪条信息是错误的

  2. 但提供具体信息也允许潜在的滥用。如果您在用户名不存在的情况下特别返回,则相反的情况可能会提醒黑客用户名确实存在,他可能会使用该信息更有效地使用暴力破解技术来破解登录

最适合您的情况总是需要权衡取舍,但出于上述安全原因,通常建议您省略特定信息

于 2013-01-21T22:34:04.493 回答