A basic user registration and login system built with PHP, HTML, jQuery, AJAX, JSON, Bootstrap, CSS, and MySQL. This project demonstrates a simple yet secure way to handle user authentication, including registration, login, and session management.
Topics: php
, mysql
, ajax
, json
, bootstrap
, jquery
, css
, user authentication
, user registration
, user-login
, session management
Step-by-Step Solution
1. Directory Structure
simple-user-authentication-system/
│
├── backend/
│ └── index.php
│
├── assets/
│ ├── css/
│ │ └── style.css
│ └── js/
│ └── script.js
│
├── db/
│ └── database.sql
│
├── includes/
│ ├── config.sample.php
│ ├── db.php
│ ├── login.php
│ ├── logout.php
│ └── register.php
│
├── src/
│ ├── login.php
│ ├── logout.php
│ └── register.php
│
├── index.html
├── register.html
├── login.html
├── README.md
└── .gitignore
2. Database Schema
db/database.sql:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`email` VARCHAR(100) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. Configuration File
Configuration settings (include/config.sample.php)
<?php
// Database configuration
define('DB_HOST', 'localhost'); // Database host
define('DB_NAME', 'user_authentication'); // Database name
define('DB_USER', 'root'); // Change if necessary
define('DB_PASS', ''); // Change if necessary
?>
4. Configure the Database Connection
Establishing database connection (include/db.php)
<?php
include 'db.php';
// Database configuration
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME;
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
// Create a new PDO instance
try {
$pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set error mode to exception
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage(); // Display error message if connection fails
}
?>
5. HTML and PHP Structure
HTML Structure (index.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="wrapper">
<h1>Welcome, Guest!</h1>
<a href="login.html">Login</a> | <a href="register.html">Sign up</a>
</div>
</body>
</html>
Registration User Structure (register.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sign Up</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="wrapper">
<h2>Sign Up</h2>
<p>Please fill this form to create an account.</p>
<span class="message"></span>
<form id="registerForm">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control">
<span class="help-block username"></span>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email">
<span class="help-block email"></span>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control">
<span class="help-block password"></span>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" name="confirm_password" class="form-control">
<span class="help-block confirm_password"></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Submit">
</div>
<p>Already have an account? <a href="login.html">Login here</a>.</p>
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
(src/register.php
)
<?php
require_once '../include/register.php';
$username = $password = $confirm_password= $email = "";
$response = [];
$response['status'] = true;
if($_SERVER["REQUEST_METHOD"] == "POST") {
if(empty(trim($_POST["username"]))) {
$response['status'] = false;
$response['field'] = 'username';
$response['message'] = "Please enter a username.";
} elseif(empty(trim($_POST["email"]))) {
$response['status'] = false;
$response['field'] = 'email';
$response['message'] = "Please enter a email.";
} elseif(empty(trim($_POST["password"]))) {
$response['status'] = false;
$response['field'] = 'password';
$response['message'] = "Please enter a password.";
} elseif(strlen(trim($_POST["password"])) < 6) {
$response['status'] = false;
$response['field'] = 'password';
$response['message'] = "Password must have at least 6 characters.";
} elseif(empty(trim($_POST["confirm_password"]))) {
$response['status'] = false;
$response['field'] = 'confirm_password';
$response['message'] = "Please confirm password.";
} elseif(trim($_POST["password"]) != trim($_POST["confirm_password"])) {
$response['status'] = false;
$response['field'] = 'confirm_password';
$response['message'] = "Password did not match.";
}else {
$username = trim($_POST["username"]);
$email = trim($_POST["email"]);
$password = trim($_POST["password"]);
$confirm_password = trim($_POST["confirm_password"]);
$password_hash = password_hash($password, PASSWORD_DEFAULT);
$response = register_user($username, $email, $password_hash);
}
}
echo json_encode($response);
?>
(include/register.php
)
<?php
require_once 'db.php';
/**
* @param $username
* @param $email
* @param $password
* @return array
*/
function register_user($username, $email, $password) {
global $pdo;
$response = [];
$response['status'] = true;
// Check if the username already exists
$sql = "SELECT id FROM users WHERE username = :username OR email = :email";
if($stmt = $pdo->prepare($sql)) {
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->bindParam(":email", $email, PDO::PARAM_STR);
if($stmt->execute()) {
if($stmt->rowCount() == 1) {
$response['status'] = false;
$response['message'] = "Username or email already exists.";
} else {
// Username is available, so insert the new user
$sql = "INSERT INTO users (username, email, password) VALUES (:username, :email, :password)";
if($stmt = $pdo->prepare($sql)) {
// Bind variables to the prepared statement
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->bindParam(":email", $email, PDO::PARAM_STR);
$stmt->bindParam(":password", $password, PDO::PARAM_STR);
// Attempt to execute the prepared statement
if($stmt->execute()) {
$response['message'] = "Registration successful!";
} else {
$response['status'] = false;
$response['message'] = "Something went wrong. Please try again later.";
}
}else{
$response['status'] = false;
$response['message'] = 'Registration failed. Please try again.';
}
}
} else {
$response['status'] = false;
$response['message'] = "Oops! Something went wrong. Please try again later.";
}
}
unset($stmt);
unset($pdo);
return $response;
}
Login User Structure (index.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="wrapper">
<h1>Welcome, Guest!</h1>
<a href="login.html">Login</a> | <a href="register.html">Sign up</a>
</div>
</body>
</html>
(src/login.php
)
<?php
require_once '../include/login.php';
$result = [];
if($_SERVER["REQUEST_METHOD"] == "POST") {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
// Check for empty fields
if (empty($username) || empty($password)) {
$response['status'] = false;
$response['message'] = 'Please fill in all fields.';
} else {
$result = login_user($username, $password);
}
echo json_encode($result);
}
?>
?>
(include/login.php
)
<?php
<?php
require_once 'db.php';
/**
* @param $username
* @param $password
* @return array
*/
function login_user($username, $password) {
global $pdo;
$response = array();
$sql = "SELECT id, username, password FROM users WHERE username = :username";
if($stmt = $pdo->prepare($sql)) {
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
if($stmt->execute()) {
if($stmt->rowCount() == 1) {
if($row = $stmt->fetch()) {
$id = $row["id"];
$username = $row["username"];
$hashed_password = $row["password"];
if(password_verify($password, $hashed_password)) {
// Password is correct, start a new session
session_start();
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
$response['status'] = true;
$response['message'] = 'Login successful!';
} else {
$response['status'] = false;
$response['message'] = 'The password you entered was not valid.';
}
}
} else {
$response['status'] = false;
$response['message'] = 'No account found with that username.';
}
} else {
$response['status'] = false;
$response['message'] = 'Oops! Something went wrong. Please try again later.';
}
}
unset($stmt);
unset($pdo);
return $response;
}
After Login User Structure (backend/index.php
)
<?php
session_start();
if (!isset($_SESSION['username'])) {
header('Location: ../index.html');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" href="../assets/css/style.css">
</head>
<body>
<div class="wrapper">
<h1>Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?>!</h1>
<a href="../src/logout.php">Logout</a>
</div>
</body>
</html>
Logout (src/logout.php
)
<?php
require_once '../include/logout.php';
logout_user();
?>
(include/logout.php
)
<?php
require_once 'db.php';
/**
* @return void
*/
function logout_user() {
session_start();
$_SESSION = array();
session_destroy();
header("location: ../backend/index.php");
exit;
}
6. JavaScript and AJAX
AJAX Handling (assets/js/script.js
)
$(document).ready(function() {
$('.help-block').hide();
$("#registerForm").submit(function(event) {
event.preventDefault();
$('.help-block').hide();
$.ajax({
url: "src/register.php",
type: "post",
dataType: 'json',
data: $(this).serialize(),
success: function(response) {
if(response.status === false){
if(response.field){
$('.' + response.field).show();
$('.' + response.field).html(response.message);
}else{
$('.message').html(response.message);
}
}else{
$('#registerForm')[0].reset();
$('#registerForm').hide();
$('h2').hide();
$('p').html(response.message + ' <a href="login.html">Please Login here</a>');
//window.location.href = 'index.html';
}
}
});
});
$("#loginForm").submit(function(event) {
event.preventDefault();
$.ajax({
url: "src/login.php",
type: "post",
dataType: 'json',
data: $(this).serialize(),
success: function(response) {
if (response.status === true) {
window.location.href = 'backend/index.php';
}
}
});
});
});
7. Stylesheet (assets/css/style.css
)
body {
font: 14px sans-serif;
}
.wrapper {
width: 350px;
padding: 20px;
margin: 0 auto;
}
.help-block {
color: red;
}
Documentation and Comments
Each part of the code has been commented to explain what it does:
-
include/config.php
: Contains the database connection configuration. -
include/register.php
: Contains helper functions for registering, logging in, and logging out users. -
include/login.php
: Contains helper functions for registering, logging in, and logging out users. -
include/logout.php
: Contains helper functions for registering, logging in, and logging out users. -
src/register.php
: Handles user registration, including form validation and submission via AJAX. -
src/login.php
: Handles user login, including form validation and submission via AJAX. -
src/logout.php
: Handles user logout. -
assets/css/style.css
: Contains basic styles for the pages. -
assets/js/script.js
: Contains the jQuery AJAX functions for handling form submissions.
This project setup and code should help you create a basic user authentication system.
Connecting Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!
If you want more helpful content like this, feel free to follow me:
Top comments (0)