Php 当验证登录凭据时,如果给定的用户名不存在,适当的响应是什么?

Php 当验证登录凭据时,如果给定的用户名不存在,适当的响应是什么?,php,mysql,security,authentication,Php,Mysql,Security,Authentication,例如,有人试图以“Bob”的名称登录,但数据库中没有Bob。是否应该通知用户没有Bob,或者程序应该简单地说“身份验证失败”(我注意到Gmail会这样做)?这部分是可用性问题,部分是效率问题。现在,程序查询数据库以查看给定用户名是否存在,如果存在,则再次查询数据库以查找相同用户名的密码哈希(冗余) 我应该只使用passwordCorrect() 您不应提供登录失败的详细原因(用户不存在或密码错误),因为这会提高安全性。除非用户名在未登录时可见(这实际上是不安全的,不应如此!) 优点是您确实可以使

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

我应该只使用
passwordCorrect()

您不应提供登录失败的详细原因(用户不存在或密码错误),因为这会提高安全性。除非用户名在未登录时可见(这实际上是不安全的,不应如此!)

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

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


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

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

  • 提供特定信息可以提高可用性,因为用户知道他提供的信息中有哪些是错误的

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


  • 最适合您的情况始终是一种权衡,但出于上述安全原因,通常建议省略特定信息

    大致来说,您可以考虑以下两点

  • 提供特定信息可以提高可用性,因为用户知道他提供的信息中有哪些是错误的

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


  • 最适合您的情况始终是一种权衡,但出于上述安全原因,通常建议您忽略特定信息

    您应该执行一个查询,同时获取用户名和密码哈希。无效用户名和无效密码的错误相同,否则,暴力黑客可以知道何时使用了有效用户名,然后只需猜测密码。您应该执行一次查询,同时获取用户名和密码哈希。无效用户名和无效密码的错误相同,否则,暴力黑客可以知道何时使用了有效的用户名,然后只需猜测密码
    //$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;
    }