1

我目前有一个运行良好的登录功能,但是我希望在该功能中添加一些内容,以便它还检查用户状态是否为1.

1= 禁止

0= 未禁止

功能:

public function doLogin($uname,$umail,$upass)
    {
        try
        {
            $stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass, status FROM users WHERE user_name=:uname OR user_email=:umail ");
            $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
            $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
            if($stmt->rowCount() == 1) 
            {
                if(password_verify($upass, $userRow['user_pass']))
                {
                    $_SESSION['user_session'] = $userRow['user_id'];
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }
    }

登录.php

if(isset($_POST['btn-login']))
{
    $uname = strip_tags($_POST['txt_uname_email']);
    $umail = strip_tags($_POST['txt_uname_email']);
    $upass = strip_tags($_POST['txt_password']);

    if(empty($uname) || empty($umail) || empty($upass)){
            $error = "Please enter all fields";
    }


    if($login->doLogin($uname,$umail,$upass))
    {
        $success = "Logged in successfully, redirecting..";
        header( "refresh:3;url=debits" );
        //$login->redirect('debits');
    }
    else
    {
        $error = "Incorrect username or password";
    }   
}

我尝试过这样做if(password_verify($upass, $userRow['user_pass']) && $userRow['status'] == 0),我认为这可行,但是当我尝试使用被禁止的帐户进行测试时,我仍然会收到错误消息Incorrect username or password,而我更愿意这样做Your account has been banned

4

2 回答 2

0

理想情况下,一个类的每个方法都应该有一个目的。如您所见,您正试图让您的方法doLogin()

  • 从数据库中获取一行
  • 验证用户名和密码组合
  • 验证用户是否启用/禁用
  • 设置会话变量

您还希望保持每个方法,特别是public方法。通常,当您只完成几行代码时,您可能希望将某些功能分解为另一种方法。

使用多种返回类型进行表单验证的一种推荐方法是抛出一个包含错误消息的异常,然后在您想要处理错误时捕获它。

我可以建议进行一些重构吗?(注意,这是未经测试的,可能包含语法错误)

public function doLogin($uname,$umail,$upass)
{
    $user = $this->fetchUserFromDatabase($uname, $umail);
    if ($user !== false || $this->isBanned($user)) {
        throw new Exception('This account has been banned');
    }
    elseif ($user === false || !$this->validatePassword($upass, $user)) {
        throw new Exception('Invalid username or password combination');
    }
    $this->startSession($user['user_id']);
    return true;
}

private function fetchUserFromDatabase($uname, $umail)
{
    $stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass, status 
        FROM users
        WHERE user_name=:uname 
        OR user_email=:umail ");
    $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
    return $stmt->fetch(PDO::FETCH_ASSOC);
}

private function isBanned(Array $user)
{
    return $user['status'] == 1;
}

private function validatePassword($upass, Array $user)
{
    return password_verify($upass, $user['user_pass'])
}

private function startSession($user_id)
{
    $_SESSION['user_session'] = $user['user_id'];
}

然后在你的另一个文件中:

if(isset($_POST['btn-login']))
{
    $uname = strip_tags($_POST['txt_uname_email']);
    $umail = strip_tags($_POST['txt_uname_email']);
    $upass = strip_tags($_POST['txt_password']);

    if(empty($uname) || empty($umail) || empty($upass)){
        $error = "Please enter all fields";
    }

    try {
        $login->doLogin($uname,$umail,$upass);
        $success = "Logged in successfully, redirecting..";
        header( "refresh:3;url=debits" );
    }
    catch (Exception $e) {
        $error = $e->getMessage();
    }
}

另一方面,您可能需要考虑让 PDO 错误try/catch为每个查询抛出异常而不是块。如果您不仅有几个查询,那么按照自己的方式去做会变得非常乏味。然后,您可以设置一个全局异常处理程序来处理任何PDOException抛出的异常。

于 2018-08-17T00:21:15.720 回答
0

我建议您返回包含正确密码布尔值和用户被禁止状态的数组。现在在验证时,检查密码正确布尔值以了解用户是否输入了正确的密码或以其他方式显示不正确的电子邮件或密码,就像您已经在做的那样。现在,如果密码正确,您可以检查状态布尔值以了解用户是否被禁止并发送适当的错误消息。

public function doLogin($uname,$umail,$upass)
{
    try
    {
        $stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass, status FROM users WHERE user_name=:uname OR user_email=:umail ");
        $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
        $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
        if($stmt->rowCount() == 1) 
        {
            if(password_verify($upass, $userRow['user_pass']))
            {
                $_SESSION['user_session'] = $userRow['user_id'];
                return ["correctPass"=>true,"banned"=> ($userRow['status']== 1) ? true : false];
            }
            else
            {
                return ["correctPass"=>false];
            }
        }
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
}

登录.php

if(isset($_POST['btn-login']))
{
    $uname = strip_tags($_POST['txt_uname_email']);
    $umail = strip_tags($_POST['txt_uname_email']);
    $upass = strip_tags($_POST['txt_password']);

    if(empty($uname) || empty($umail) || empty($upass)){
        $error = "Please enter all fields";
    }


    $validation = $login->doLogin($uname,$umail,$upass))
    if($validation["correctPass"])){
        if($validation["banned"]){
            $error = "User has been banned";
        }else{
            $success = "Logged in successfully, redirecting..";
            header( "refresh:3;url=debits" );
            //$login->redirect('debits');
        }
    }
    else{
        $error = "Incorrect username or password";
    }   
}
于 2018-08-17T00:16:03.090 回答