'PHP MySql login with either email or username

i cant understand why i can't login with email but only with username.

This is my login form:

<form action="includes/login.inc.php" method="post">
  <div class="inputBox">
  <input type="text" name="uname" placeholder="Username">
  <input type="password" name="upass" placeholder="Password"> 
  </div>
  <input type="submit" name="submit" value="Login">
</form>

This is my register form:

<form action="includes/signup.inc.php" method="post">
  <div class="inputBox">
  <input type="text" name="uname" placeholder="Username">
  <input type="text" name="uemail" placeholder="E-mail">
  <input type="password" name="upass" placeholder="Password"> 
  <input type="password" name="urpass" placeholder="Repeat Password"> 
  </div>
  <input type="submit" name="submit" value="Sign Up">
</form>

My includes files:

Signup include file:

<?php

if(isset($_POST['submit'])){


    //Grabbing the Data
    $uid = $_POST["uname"];
    $uemail = $_POST["uemail"];
    $upass = $_POST["upass"];
    $urpass = $_POST["urpass"];

    //Instantiate SignupContr class
    include "../classes/dbh.classes.php";
    include "../classes/signup.classes.php";
    include "../classes/signup-contr.classes.php";
    $signup = new SignupContr($uid, $uemail, $upass, $urpass);

    //Running error handlers and user signup
    $signup -> signupUser();

    //Going back to home page
    header("location:../index.php?error=none");

}

login include file:

<?php

if(isset($_POST['submit'])){


    //Grabbing the Data
    $uid = $_POST["uname"];
    $upass = $_POST["upass"];

    //Instantiate SignupContr class
    include "../classes/dbh.classes.php";
    include "../classes/login.classes.php";
    include "../classes/login-contr.classes.php";
    $login = new loginContr($uid, $upass);

    //Running error handlers and user signup
    $login -> loginUser();

    //Going back to home page
    header("location:../index.php?error=none");

}

logout include file:

<?php 

session_start();
session_unset();
session_destroy();

//Going back to home page
header("location: ../index.php");

MY CLASSES FILES ->

signup classes file:

<?php


class Signup extends Dbh {

    protected function setUser($uid, $upass, $uemail) {
        $stmt = $this -> connect() -> prepare('INSERT INTO users (users_name,  users_pass, users_email) VALUES (?, ?, ?)');

        $hashedPass = password_hash($upass, PASSWORD_DEFAULT);

        if(!$stmt -> execute(array($uid, $hashedPass, $uemail))){
            $stmt = null;
            header("location: ../index.php?error=stmtFailed");
            exit();
        }

        $stmt = null;
    }

    protected function checkUser($uid, $uemail) {
        $stmt = $this -> connect() -> prepare('SELECT users_name FROM users WHERE users_name = ? OR users_email = ?;');

        if(!$stmt -> execute(array($uid,$uemail))){
            $stmt = null;
            header("location: ../index.php?error=stmtFailed");
            exit();
        }


        $resultCheck;
        if($stmt -> rowCount() > 0) {
            $resultCheck = false;
        }
        else {
            $resultCheck = true;
        }

        return $resultCheck;
    }
  
}

signup-contr classes file:

<?php


class SignupContr extends Signup {


    private $uid;
    private $uemail;
    private $upass;
    private $urpass;



    public function __construct($uid, $uemail, $upass, $urpass) {

        $this -> uid = $uid;
        $this -> uemail = $uemail;
        $this -> upass = $upass;
        $this -> urpass = $urpass;
    }


    //Error Handlers

    public function signupUser() {
        if($this -> emptyInput() == false) {
            //Echo empty input

            header("location: ../index.php?error=emptyinput");
            exit();
        }
        if($this -> invalidUid() == false) {
            //Echo invalid username
            
            header("location: ../index.php?error=invalidusername");
            exit();
        }
        if($this -> invalidEmail() == false) {
            //Echo invalid email

            header("location: ../index.php?error=invalidemail");
            exit();
        }

        if($this -> pwdMatch() == false) {
            //Echo  password match

            header("location: ../index.php?error=invalidpasswordmatch");
            exit();
        }

        if($this -> uidTakenCheck() == false) {
            //Echo Username or email taken

            header("location: ../index.php?error=usernameoremailtaken");
            exit();
        }

        $this -> setUser($this -> uid, $this -> upass, $this -> uemail);
    }

  
    private function emptyInput() {
        $result;

        if(empty($this -> uid || empty($this -> uemail) || empty($this -> upass) || empty($this -> urpass))) {
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }

    private function invalidUid() {
        $result;

        if(!preg_match("/^[a-zA-Z0-9]*$/", $this-> uid)){
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }

    private function invalidEmail() {
        $result;

        if(!filter_var($this-> uemail, FILTER_VALIDATE_EMAIL)) {
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }


    private function pwdMatch() {
        $result;

        if($this -> upass !== $this -> urpass) {
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }

    private function uidTakenCheck() {
        $result;

        if(!$this -> checkUser($this -> uid, $this -> uemail)) {
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }
}

login classes file:

<?php


class Login extends Dbh {

    protected function getUser($uid, $upass) {
        $stmt = $this -> connect() -> prepare('SELECT users_pass FROM users WHERE users_name = ? OR users_email = ?;');


        if(!$stmt -> execute(array($uid, $upass))){
            $stmt = null;
            header("location: ../index.php?error=stmtFailed");
            exit();
        }



        if($stmt -> rowCount() == 0) {
            $stmt = null;
            header("location: ../index.php?error=usernotfound");
            exit();
        }

        $passHashed = $stmt -> fetchAll(PDO::FETCH_ASSOC);
        $checkPass = password_verify($upass, $passHashed[0]["users_pass"]);
 

        
        if($checkPass == false) {
            $stmt = null;
            header("location: ../index.php?error=wrongpassword");
            exit();
        }elseif($checkPass == true) {
            $stmt = $this -> connect() -> prepare('SELECT * FROM users WHERE users_name = ? OR users_email = ? AND users_pass = ?;');

            if(!$stmt -> execute(array($uid, $uid, $upass))){
                $stmt = null;
                header("location: ../index.php?error=stmtFailed");
                exit();
            }
            
            if($stmt -> rowCount() == 0) {

                $stmt = null;
                header("location: ../index.php?error=usernotfound");
                exit();
            }

            $user = $stmt -> fetchAll(PDO::FETCH_ASSOC);

    

            session_start();
            $_SESSION["userid"] = $user[0]["users_id"];
            $_SESSION["useruid"] = $user[0]["users_name"];

            $stmt = null;

        }


    }

  
  
}

login-contr classes file:

<?php


class loginContr extends Login {


    private $uid;
    private $upass;



    public function __construct($uid, $upass) {

        $this -> uid = $uid;
        $this -> upass = $upass;
    }


    //Error Handlers

    public function loginUser() {
        if($this -> emptyInput() == false) {
            //Echo empty input

            header("location: ../index.php?error=emptyinput");
            exit();
        }
        
        $this -> getUser($this -> uid, $this -> upass);
    }

  
    private function emptyInput() {
        $result;

        if(empty($this -> uid || empty($this -> upass))) {
            $result = false;
        }
        else {
            $result = true;
        }

        return $result;
    }

 
}

Structure of the users table:

   CREATE TABLE users (
    
    users_id int(11) AUTO_INCREMENT PRIMARY KEY not null,
    users_name TINYTEXT not null,
    users_email TINYTEXT not null,
    users_pass LONGTEXT not null
);

Records of users table:

enter image description here

SOLUTION:

   <?php


class Login extends Dbh {

    protected function getUser($uid, $upass) {
        $stmt = $this -> connect() -> prepare('SELECT users_pass FROM users WHERE users_name = ? OR users_email = ?;');
   

   
        if(!$stmt -> execute(array($uid, $uid))){
            $stmt = null;
            header("location: ../index.php?error=stmtFailed");
            exit();
        }
 
        if($stmt -> rowCount() == 0) {
            $stmt = null;
            header("location: ../index.php?error=usernotfound");
            exit();
        }

 
        $passHashed = $stmt -> fetchAll(PDO::FETCH_ASSOC);
        $checkPass = password_verify($upass, $passHashed[0]["users_pass"]);

      

        
        if($checkPass == false) {
            $stmt = null;
            header("location: ../index.php?error=wrongpassword");
            exit();
        }elseif($checkPass == true) {
            $stmt = $this -> connect() -> prepare('SELECT * FROM users WHERE (users_name = ? OR users_email = ?) AND users_pass = ?;');

            if(!$stmt->execute(array($uid,$uid,$passHashed[0]['users_pass']))){
                $stmt = null;
                header("location: ../index.php?error=stmtFailed");
                exit();
            }
            
            if($stmt -> rowCount() == 0) {

                $stmt = null;
                header("location: ../index.php?error=usernotfoundalt");
                exit();
            }

            $user = $stmt -> fetchAll(PDO::FETCH_ASSOC);

    

            session_start();
            $_SESSION["userid"] = $user[0]["users_id"];
            $_SESSION["useruid"] = $user[0]["users_name"];

            $stmt = null;

        }


    }

}

I had to change the if(!$stmt -> execute(array($uid, $upass))) to
if(!$stmt -> execute(array($uid, $uid))). Also the

$stmt = $this -> connect() -> prepare('SELECT * FROM users WHERE users_name = ? OR users_email = ? AND users_pass = ?;');
 to `$stmt = $this -> connect() -> prepare('SELECT * FROM users WHERE (users_name = ? OR users_email = ?) AND users_pass = ?;');`

and finally the if(!$stmt->execute(array($uid,$uid,$passHashed[0]['users_pass']))) to if(!$stmt ->execute(array($uid,$uid,$passHashed[0]['users_pass'])))



Solution 1:[1]

<?php

class Login extends Dbh {

    protected function getUser($uid, $upass) {
        $stmt = $this->connect()->prepare("SELECT users_pass FROM users WHERE users_name = ? OR users_email = ?;");

        if(!$stmt->execute([$uid, $uid])){
            header("location: ../index.php?error=stmtFailed");
            exit;
        }

        if($stmt->rowCount() === 0) {
            header("location: ../index.php?error=usernotfound");
            exit;
        }

        $passHashed = $stmt->fetch(PDO::FETCH_ASSOC);
        $checkPass = password_verify($upass, $passHashed["users_pass"]);
        
        if (!$checkPass) {
            header("location: ../index.php?error=wrongpassword");
            exit;
        }

        $stmt = $this->connect()->prepare("SELECT * FROM users WHERE (users_name = ? OR users_email = ?) AND users_pass = ?;");

        if(!$stmt->execute([$uid, $uid, password_hash($upass, PASSWORD_DEFAULT)])){
            header("location: ../index.php?error=stmtFailed");
            exit;
        }
        
        if($stmt->rowCount() === 0) {
            header("location: ../index.php?error=usernotfound");
            exit;
        }

        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        session_start();
        $_SESSION["userid"] = $user["users_id"];
        $_SESSION["useruid"] = $user["users_name"];
    }
}
  • On line 5 you are passing $uid and $upass as parameters, when in fact it should be [$uid, $uid];
  • On line 15, as it's a login script, usually only a single result is expected for the given data, so you can use $stmt->fetch(PDO::FETCH_ASSOC). Avoiding having to access the first index every time;
  • On line 22 the conditions of users_name and users_email should be grouped together;
  • On line 23 you are passing the password in plain text to the query, but on line 16 you are using the password_verify() function to validate the password, which indicates that the stored password is encrypted (good), in this if you should encrypt the password before passing it to the query;

You can also change one of the usernotfound error messages to usernotfoundalt and see which of the two it is triggering the error. Also check if user passwords are saved encrypted in the database.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1