1

I am a relative newcomer to PHP/Apache web server so please bear with.

I am attempting to implement a login system using PHP. At the moment, a form sends the login data to a script called auth.php. This script then validates the login details. If the login details are correct, then the script uses readfile to send the desired authenticated page to the end user. If the login details are not correct, then the script redirects the user back to the login page.

The problem is that readfile sends the raw PHP page without running the PHP code. I would like to run the PHP and then send the output of this. My initial question is how could this be accomplished?

However, I suspect the actual issue is how I'm handling authentication, and that I need to approach authenticating users in a different manner. If this is the case, could you please point me in the direction of a guide on how to do this?

Relevant code snippets:

Login form

  <form class="form-signin" method="post" action="./auth.php?target=dashboard">
    <h2 class="form-signin-heading">Admin Sign In</h2>
    <label for="inputEmail" class="sr-only">Email address</label>
    <input type="email" id="email" name="email" class="form-control" placeholder="Email address" required autofocus>
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="rememberme" value="remember-me"> Remember me
      </label>
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
  </form>

auth.php (n.b. hashing the password is disabled for testing)

<?php

        function authenticate_user(string $uname, string $pwd) {
                // return true or false

                $hashed = $pwd;//password_hash($pwd, null);

                $admin_uname = "test@example.com";
                $admin_pwd = "test";

                return $hashed === $admin_pwd and $uname === $admin_uname;
        }


        namespace admin;

        $dir = getcwd();
        $is_auth = authenticate_user($_POST["email"], $_POST["password"]);

        if($is_auth) {
                $extension = $_GET["target"].".php";
                $full = $dir."/".$extension;
                readfile($full);
        }
        else {
                $full = $_SERVER["PHP_SELF"]."/../?FAIL";
                //echo $full;
                header("Location: ".$full);
        }

?>

Current dashboard.php

<!DOCTYPE HTML>
<html>
<head>
<title>Dashboard</title>
</head>

<body>

        <p>Success</p>

<?php
        echo "<p>Flag</p>";
?>

</body>
</html>

Current output

<html><head>
<title>Dashboard</title>
</head>

<body>

    <p>Success</p>

<!--?php
    echo "<p-->Flag<p></p>";
?&gt;

</body></html>

Desired output

<html><head>
<title>Dashboard</title>
</head>

<body>

    <p>Success</p>
    <p>Flag</p>

</body></html>

Any pointers or advice would be greatly appreciated, cheers :)

p2titus
  • 21
  • 4

1 Answers1

1

What you would normally do is to start a session once you confirm the user's credentials, then send them back to the browser and let them navigate to the authenticated page (or you could redirect the browser there). In the failed path of your code, you send back a location header and that redirects the user's browser to the desired page. You could do the same for the authenticated path after starting a session.

Mind that your code has some other problems. Your dashboard.php actually does not check whether a user is authenticated or not. So anyone navigating to "/dashboard.php" will be able to view the page. You would have to check at the beginning of the dashboard.php script whether the user has an active session, etc.

What is more, mixing HTML and PHP is not recommended these days, unless you just use PHP to print some variables.

Have a look at some tutorials that show some good practices for building modern websites with PHP. These should cover topics like authentication or user routing. Even better, you could start your adventure by learning some web frameworks — Symfony, Laravel, Cake, CodeIgniter, Yii, etc. (the first two are the most popular in the PHP world) These frameworks have some very good free learning resources (and some amazing paid ones, if you don't mind, e.g. https://symfonycasts.com/) Anyway, the frameworks implement many features in a modern and organized way, and that will help you to cope with some common solutions used in websites (things like logging users in, database connections, rendering templates, routing, etc.)

Michal Trojanowski
  • 10,641
  • 2
  • 22
  • 41