Login page is not working properly while using PDO prepared statement in php

I am trying to make a login page using PDO prepared statement. My sample code for login.php is as follows:

   <?php
    session_start();
    if(isset($_SESSION['user']))
    {
        header("location:admin.php");
        exit;
        
    }
    include('../php/config.php');
    $uname = hash('sha512', $_POST['lgnID']);
    $pass =  hash('sha512', $_POST['password']);
    $stmt = $db->prepare("SELECT * FROM admin WHERE uname= ?");
$stmt->execute([$uname]);
// this will fetch first record from query or false if record does not exist
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result) {
    if ($pass == $result['password']) {
        $_SESSION['user'] = $uname;
        $_SESSION['pass'] = $pass;    
        $_SESSION['loggedin']= 1;
        header("location:admin.php");
        exit;
    } else {
        echo "Login ID and Password did not Match";
    }
} else {
     echo "Admin login ID doesn't exist";
}
?>

But the problem is after I put valid credentials while login, I am not redirected to admin.php page which I am supposed to do. Is there anything wrong in the code?

Are you sure the usernames are hashed in the database? This is not common practice.

yes I am sure.

Also, let me clean that up for you a bit:

<?php

session_start();

if (isset($_SESSION['user']) && $_SESSION['user'] != '') {
    header("Location:admin.php");
}

require_once "../php/variables.php";

$dbh=new PDO('mysql:dbname=$dbms;host=$server', $root, $password);
if (isset($_POST['lgnID']) && isset($_POST['password'])) {
    $uname = hash('sha512', $_POST['lgnID']);
    $pass =  hash('sha512', $_POST['password']);
 
    $query = $dbh->prepare("SELECT * FROM admin WHERE uname=?");
    $query->execute(array($uname));

    while ($row = $query->fetch()) {
        if ($row['password'] === $pass) {
            $_SESSION['user'] = $uname;
            $_SESSION['loggedin'] = 1;
            header("Location:admin.php");
            exit;
        }
    }
    echo "<h2>Username/Password is Incorrect.</h2>";
}

Still Not redirecting to admin.php page.

Your first line of code in the first post seems to have a space before the opening PHP tag - have you removed that as per the post by @rpkamp ? It might not be obvious that it’s been removed, but if the browser has received that space, you won’t be able to do a header redirect, you’ll get a “headers already sent” error.

Slightly separately, hashing passwords in that way doesn’t seem to be the preferred way now - you should read up on password_hash() and password_verify() functions.

In this code

while($r=$sql->fetch()){
  $p=$r['password'];
 }

will you be allowing more than one row with the same username? If not, there’s no need for a while() loop, just call fetch() once.

2 Likes

I have removed the space. still Not working

It could also affect the session.

1 Like

OK, can we see the code as it is now? And are you sure that you’re using the correct values for the comparison? Do you really store the username in hashed form as well as the password, just noticed @rpkamp asked above?

Nice to see you have gotten over your “SELECT *” phobia:)

My current code:

<?php

session_start();

if (isset($_SESSION['user']) && $_SESSION['user'] != '') {
    header("Location:admin.php");
}

require_once "../php/variables.php";

$dbh=new PDO('mysql:dbname=$dbms;host=$server', $root, $password);
if (isset($_POST['lgnID']) && isset($_POST['password'])) {
    $uname = hash('sha512', $_POST['lgnID']);
    $pass =  hash('sha512', $_POST['password']);
 
    $query = $dbh->prepare("SELECT * FROM admin WHERE uname=?");
    $query->execute(array($uname));

    while ($row = $query->fetch()) {
        if ($row['password'] === $pass) {
            $_SESSION['user'] = $uname;
            $_SESSION['loggedin'] = 1;
            header("Location:admin.php");
            exit;
        }
    }
    echo "<h2>Username/Password is Incorrect.</h2>";
}

?>

Ans yes I am using the correct values for comparison and I have stored the username and password both in hashed form.

What is the database table layout like?

I assume you do have error reporting on.
Correct?

Missing an exit; after your first header.

Have you any experience at all with debugging? Try adding:

$uname = hash('sha512', $_POST['lgnID']);
$pass =  hash('sha512', $_POST['password']);
die('uname  ' . $_POST['lgnID'] . ' ' . $uname);

And see if you get the expected results.

2 Likes

The point above is a good one - which of the header redirects are you expecting it to be doing that it is not? If it’s the first one, then you do need that exit; line as @ahundiak mentioned above, so it doesn’t execute the rest of the code.

added the exit but same result.

How far through your code does it get? Add some echo statements so you can track where it’s going and (more to the point) where it stops. Can you show the HTML for the form too?

So think about what that means. The fact that the die is not being reached implies that you are never getting to your query. Try this:

<?php
error_reporting(E_ALL);
session_start();
var_dump($_SESSION);
var_dump($_POST);
die('got here');

And see if you are getting the expected data.

I have changed my code a bit. Now I have confirmed that The password is being matched but after that header part is not working. Please check my edited post.