If you want to create a simple login page in PHP, you can use MySQL as a database.
However, you should be aware that a database must be created first. Then, you can connect it to PHP. There are several ways you can do this.
We should be aware that a database must be created first. Then, we can connect it to PHP. We will need a users
table to hold our users' records. Run the command below in the MySQL console to create a users
table:
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(30) UNIQUE NOT NULL,
password VARCHAR(250) NOT NULL
)
Since we are using PDO in PHP when working with the database. In this step, we will create a function to create a PDO connection:
function connection($host, $database, $username, $password)
{
try {
$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
} catch (PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
}
This function is pretty straightforward. It needs some database-related credentials.
Before we let users login, we must register their accounts first. This function will just do that:
function register($connection, $email, $password)
{
$passwordHashed = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users ( email, password) VALUES ( :email, :password)";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email, 'password' => $passwordHashed]);
}
Note that we should never store a plain password in a database. Here we are using password_hash
to hash it before storing it in the database.
Next, we need to authenticate a user:
function login($connection, $email, $password)
{
$sql = "SELECT * FROM users WHERE email = :email";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
if (password_verify($password, $user['password'])) {
return $user;
} else {
return false;
}
} else {
return false;
}
}
The logic for login
is:
password_verify
function. This function is paired with password_hash
previously when we hash the plain password.Let's group all the functions above into a functions.php
file:
<?php
function connection($host, $database, $username, $password)
{
try {
$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
} catch (PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
}
function register($connection, $email, $password)
{
$passwordHashed = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users ( email, password) VALUES ( :email, :password)";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email, 'password' => $passwordHashed]);
}
function login($connection, $email, $password)
{
$sql = "SELECT * FROM users WHERE email = :email";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
if (password_verify($password, $user['password'])) {
return $user;
} else {
return false;
}
} else {
return false;
}
}
Let's create a simple CLI tool for creating a user account called create.php
:
<?php
if (count($argv) < 3) {
echo 'Usage: php create.php email password;'.PHP_EOL;
return;
}
include_once 'functions.php';
$connection = connection('localhost', 'login', 'root', 'root');
register($connection, $argv[1], $argv[2]);
?>
This script is pretty simple, it takes an email and a password and creates a user account in the database using the register
function we created previously.
For this to work for you, you need to provide the correct credentials in this line: $connection = connection('localhost', 'login', 'root', 'root');
.
Now run the script from your command line:
php create.php email@gmail.com password
It will create a user account with the email email@gmail.com
and password
as the password.
Let's create the login page using Tailwind CSS:
<?php
session_start();
if (isset($_SESSION['login']) && $_SESSION['login']) {
header('Location: dashboard.php');
}
include 'functions.php';
$msg = '';
$success = true;
if (!empty($_POST)) {
$email = $_POST['email'];
$password = $_POST['password'];
$connection = connection('localhost', 'login', 'root', 'root');
if (login($connection, $email, $password)) {
$_SESSION['login'] = true;
header('Location: dashboard.php');
}
$success = false;
$msg = 'Invalid username or password';
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="">
<div class="max-w-xl mx-auto h-screen flex flex-col items-center justify-center space-y-4">
<?php if (!empty($msg) && !$success): ?>
<div class="w-full bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"><?= $msg; ?></span>
</div>
<?php endif; ?>
<h1 class="text-3xl font-bold">
Login
</h1>
<form class="bg-white shadow-lg rounded px-8 pt-6 pb-8 mb-4 flex flex-col w-full"
enctype="multipart/form-data"
action="index.php"
method="post">
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Email
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="email"
id="email"
autocomplete="false"
type="text"
placeholder="Email">
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Password
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="password"
id="password"
autocomplete="false"
type="password"
placeholder="Password">
</div>
<div class="mb-6">
<button
id="payButton"
class="bg-indigo-500 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="submit">
Login
</button>
</div>
</form>
</div>
</div>
</body>
</html>
On top of the page, we are using PHP's session to restrict user access:
session_start();
if (isset($_SESSION['login']) && $_SESSION['login']) {
header('Location: dashboard.php');
}
If a user has already logged in, we will redirect them to dashboard.php
.
When we detect a POST
request, we use the functions created previously to authenticate a user:
if (!empty($_POST)) {
$email = $_POST['email'];
$password = $_POST['password'];
$connection = connection('localhost', 'login', 'root', 'root');
if (login($connection, $email, $password)) {
$_SESSION['login'] = true;
header('Location: dashboard.php');
}
$success = false;
$msg = 'Invalid username or password';
}
To make this work for you, you need to update this line using your credential: $connection = connection('localhost', 'login', 'root', 'root');
Lastly, we need to create the dashboard page, this page is only for authenticated users.
Create a file dashboard.php
with the content below:
<?php
session_start();
if (!empty($_POST)) {
unset($_SESSION['login']);
}
if (!$_SESSION['login']) {
header('Location: index.php');
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="">
<div class="max-w-xl mx-auto h-screen flex flex-col items-center justify-center space-y-4">
<h1 class="text-3xl font-bold">
Welcome
</h1>
<p class="bg-white shadow-lg rounded px-8 pt-6 pb-8 mb-4 flex flex-col w-full h-48">
Welcome to the dashboard
</p>
<form
action="dashboard.php"
method="post">
<input type="hidden" name="method" value="POST"/>
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" type="submit">
Logout
</button>
</form>
</div>
</div>
</body>
</html>
Take look at the top of the page:
session_start();
if (!empty($_POST)) {
unset($_SESSION['login']);
}
if (!$_SESSION['login']) {
header('Location: index.php');
}
We did two things here. when we detect a POST
request, which is sent by the log-out button, we will unset the $_SESSION['login']
.
The other thing we did is to protect the dashboard, if $_SESSION['login']
is not set, we send the user to the index page.
Now we have completed a simple login page in PHP with the database. You have learned how we are using password_hash
and password_verify
to handle password authentication. You also learned to use $_SESSION
to restrict access rights.