如何在使用PHP登录之前检查用户是否被禁止

时间:2018-08-16 23:37:14

标签: php

我目前有一个登录功能,该功能可以正常工作,但是我正在向该功能中添加一些内容,因此它还可以检查用户状态是否为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();
        }
    }

login.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

2 个答案:

答案 0 :(得分: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();
    }
}

login.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";
    }   
}

答案 1 :(得分:0)

理想情况下,类的每个方法都应具有单一目的。如您所见,您正在尝试将方法doLogin()应用于:

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

您还希望每个方法都保持较小,尤其是public个方法。通常,当您仅浏览几行代码时,可能希望将某些功能分解为另一种方法。

推荐的do form validation with multiple return types方法是抛出一个包含错误消息的异常,然后在您想处理该错误时捕获它。

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

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();
    }
}

另一方面,您可能希望为每个查询考虑getting PDO errors to throw Exceptions而不是try/catch块。如果您不只是几个查询,那么按它的方式进行操作将变得非常繁琐。然后,您可以设置全局异常处理程序以处理任何引发的PDOException