-3

I dont really know whats really happening but I cant login even I enter the right UserID and Password it still doesnt make me go to my home page. I dont really know what are the error becasue it doesnt show up it just say "incorrect Credentials". am I missing something? here is my code:

<?php

include "includes/config.php";

session_start();
if (isset($_POST['loginbutton'])) {

    $username = mysqli_real_escape_string($con, $_POST['user']);
    $password = mysqli_real_escape_string($con, $_POST['password']);

    $sql_query = "SELECT * FROM tbl_useraccounts WHERE employee_id = '$username' AND password ='$password' LIMIT 1";
    $result = mysqli_query($con, $sql_query);
    
    $row = mysqli_fetch_array($result);

    $passwordhashed = password_verify($password, $row['password']);
    if ($passwordhashed) {
        if ($_SESSION['usertype'] == 'Admin') {
            $_SESSION['username'] = $username;
            echo "<script>alert('Successfully logged in!');</script>";
            header('location: HomeForAdmin.php');
            die();
        } elseif ($_SESSION['usertype'] == 'SuperAdmin') {
            $_SESSION['username'] = $username;
            echo "<script>alert('Successfully logged in!');</script>";
            header('location: HomeForSuperAdmin.php');
            die();
        } else {
            echo "<script>alert('Incorrect username and password!');document.location='login2.php'</script>";
        }
    } else {
        echo "<script>alert('Incorrect credentials!');document.location='login2.php'</script>";
    }

    $_SESSION['username'] = $row['employee_id'];
    $_SESSION['password'] = $row['password'];
    $_SESSION['usertype'] = $row['usertype'];
    $_SESSION['first_name'] = $row['FirstName'];
    $_SESSION['last_name'] = $row['LastName'];
}
waterloomatt
  • 3,662
  • 1
  • 19
  • 25
  • 2
    Please note that the way you're building your query is unsafe. You're open to [SQL injection](https://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work). You should use [prepared statements](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) or [PDO](https://www.php.net/manual/en/book.pdo) instead. [Escaping](https://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not enough. – El_Vanja Dec 17 '20 at 21:22
  • 2
    And also by escaping the password, you potentially change it before it's used for comparison, which can in turn lead to a mismatch, even though the user entered the correct one. – El_Vanja Dec 17 '20 at 21:22
  • @El_Vanja to be honest Security is kinda less of my concerned because I still dont know much about it im still learning the most outer shell of php and html, but I will maybe study on security in my higher years. Thank you. – Rappa Ashura Dec 17 '20 at 21:35
  • I understand it may be a bit overwhelming at the moment. Just know that prepared statements aren't really complicated and that it's good to use them for several reasons (not just the injection part). I suggest you look into their syntax and start learning them because good habits are made early. You don't need to understand everything they do, just learning how to write them will do. – El_Vanja Dec 17 '20 at 21:43
  • I see OP uses `password_verify`, but then what is `AND password ='$password'`. I removed my comment, which I still think was helpful. – Dharman Dec 17 '20 at 22:56
  • @Dharman my understanding is that they weren't getting any results back from the query with the plain text password incorporated. Presumably indicating that it was hashed in the database? Although we don't know for sure! – Steven Dec 17 '20 at 23:02

1 Answers1

1

Prepared statements

Prepared statements are used to protect SQL queries against malicious/malformed user input.

The general layout of a prepared statement is as follows:

PDO

// Define database connection parameters
$db_host = "127.0.0.1";
$db_name = "name_of_database";
$db_user = "user_name";
$db_pass = "user_password";

// Create a connection to the MySQL database using PDO
$pdo = new pdo(
    "mysql:host={$db_host};dbname={$db_name}",
    $db_user,
    $db_pass,
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => FALSE
    ]
);

// The SQL query using ? as a place holder for the variable we want to insert
$sql = "SELECT column_1, column_2, column_3 FROM table WHERE column_x = ?";

// Prepare the query structure
$query = $pdo->prepare($sql);

// Run the query binding $variable to the ?
// i.e. the query becomes:
//      SELECT * FROM table WHERE column = "$variable"
$query->execute([$variable]);

// Fetch the first/next row into the $result variable
$result = $query->fetch(PDO::FETCH_ASSOC); // Access like: $result["column_1"];

// Other way to fetch data...
# $result = $query->fetch(PDO::FETCH_NUM); // Access like: $result[0];
# $result = $query->fetchAll();            // Access likeL $result[0]["column_1"];
# $result = $query->fetchObject();         // Access like: $result->column_1;

mysqli

// Define database connection parameters
$db_host = "127.0.0.1";
$db_name = "name_of_database";
$db_user = "user_name";
$db_pass = "user_password";

// Make connection to the database
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

// The SQL query using ? as a place holder for the variable we want to insert
$sql = "SELECT column_1, column_2, column_3 FROM table WHERE column_x = ?";

// Prepare the query structure
$query = $mysqli->prepare($sql);

// Bind the STRING $variable to the ? placeholder in the SQL
$query->bind_param("s", $variable);

// Run the query
$query->execute();

// Store the result
$query->store_result();

// Bind the returned values
$query->bind_result($column_1, $column_2, $column_3);

// Fetch the first/next row
$query->fetch();

//Access as a standard PHP variable...
echo $column_1;

PHP redirects

Using redirects like the following won't work because you can't output data to the page (echo) and then cause a redirect.

echo "<script>alert('Successfully logged in!');</script>";
header('location: HomeForSuperAdmin.php');

Session ifs

The following checks to see if the value in $_SESSION["usertype"] is set to Admin or SuperAdmin.

if ($_SESSION['usertype'] == 'Admin'){
    // Additional code...
}
elseif ($_SESSION['usertype'] == 'SuperAdmin'){
    // Additional code...
}

The issue here is that as we are only now logging in there shouldn't be a value in that variable!

There would only be a value there if the user was already logged on. In your code it should actually be written as:

if ($row['usertype'] == 'Admin'){
    // Additional code...
}
elseif ($row['usertype'] == 'SuperAdmin'){
    // Additional code...
}

LIMIT in your SQL

You don't need to use limit in your SQL query for two reasons:

  1. The username field should be unique (i.e. there is only one corresponding row)
  2. You're not accessing the row in a loop you are only taking the first row. So even if there was multiple rows returned you'd only see one.

Flow

Bear in mind that, for the most part, we don't want to have a dozen nested if statements in our programs it makes it complicated to follow and is harder to debug, maintain, etc.

if(expression a){
    if(expression b){
        if(expression c){
            // Some extra random code...
            if(expression d){
                 // Some code to work with...
            }
            else{
                // Some code...
            }
        }
        else{
            // Some code...
        }
    }
    else{
        // Some code...
    }
}
else{
    // Some code...
}

Instead, if we streamline the code so that it runs from top to bottom then it tends to be easier to follow:

if(expression a){
    // Do something...
}

if(expression b){
    // Do something else...
}

Obviously this isn't always possible - sometimes it makes more sense to nest(!) - but going too many levels with if statements can be very tricky to work with.

In your case though you're using if statements to check specific conditions have been met and if they haven't then the code should stop executing and display an error or redirect...

if(username and password have not been entered){
    echo "ERROR: Username and Password are empty";
    exit;
}

// If the user didn't input values then we would never get this far...

if(user doesn't exist in database){
    echo "ERROR: Username doesn't exist!";
    exit;
}

// If the user doesn't exist in the database then we never get this far...

if(password matches){
    echo "Success! The user is logged on.";
}

Adjusted code

include "includes/config.php";

session_start();

// Check to see if the user is already logged on. If they are then
// we want to redirect them to an error page.
if(isset($_SESSION["username"])){
    header("location:errorpage.php?error_code=1");
    exit;
}

// Assign POST variables to PHP variables. If the POST variables
// don't exist (haven't been submitted) then set the value to NULL
// so that we can use it in the IF statement easily.
$username = $_POST['user']      ?? NULL;
$password = $_POST['password']  ?? NULL;


// Check to make sure that the user has entered something into the
// username and password fields. If they haven't then we're going
// to handle them with a redirect.
if(!$username || !$password){
    header("location:errorpage.php?error_code=2");
    exit;
}

$user_sql = "
    SELECT password, usertype, FirstName, LastName
    FROM tbl_useraccounts
    WHERE employee_id = ?
";
$user_query = $pdo->prepare($user_sql);
$user_query->execute([$username]);

// Get the user from the database. If the username doesn't exist then
// redirect the user to approriate error page.
if( !($user = $user_query->fetchObject() ){
    header("location:errorpage.php?error_code=3");
    exit;
}

// If the user does exist then we verify the password supplied by the user
// against the one stored in the database. If it doesn't match then we'll
// redirect them to an approriate error page.
if(!password_verify($password, $user->password)){
    header("location:errorpage.php?error_code=4");
    exit;
}

// Set the usertype and username to the sesson SUPER GLOBAL.
// You don't need to set all of the variables (name etc.)
// if you need them get them from the database at the time!
$_SESSION["usertype"] = $user->usertype;
$_SESSION["username"] = $username;

//Redirect the user to the appropriate admin page
$usertype_redirect_locations = [
    "Admin"      => "adminpage.php",
    "SuperAdmin" => "superadminpage.php"
];
header("location:{$usertype_redirect_locations[$user->usertype]}");
Steven
  • 6,053
  • 2
  • 16
  • 28
  • I like this answer, but it is too long. If you have to explain so many things then it means that question should probably be closed and deleted. The question needs details, focus or an MCVE. Answering such questions usually is a waste of time, even if you provide good answers like this one. – Dharman Dec 17 '20 at 23:01
  • your answer that you given is for logging in with security right?. I will look into this if I had time. thank you! – Rappa Ashura Dec 19 '20 at 08:17
  • @RappaAshura Yes.. Assuming that you used `password_hash` when registering users. – Steven Dec 19 '20 at 11:38