🌙
Happy Karwa Chauth! Wishing all couples a blessed Karwa Chauth. May your bond grow stronger every year. From Team Job...
💬 Share
Web Development Tutorials

Secure PHP Login System Tutorial: Password Hashing, Sessions and Brute-Force Limits

Admin panels need logins that resist hacking. This PHP login system tutorial covers hashing, sessions, CSRF and brute-force protection with clean code.

In this article · 8 sections
  1. 1. Users table
  2. 2. Create a user with a hashed password
  3. 3. Secure session settings
  4. 4. The login handler
  5. 5. Protect admin pages
  6. 6. Logout
  7. Extra hardening
  8. FAQs
  9. Should I build my own login or use a framework?
  10. How long should sessions last?

Almost every custom website needs an admin area: bookings, enquiries, blog posts. A PHP login system done wrong is one of the easiest ways for a site to get hacked. Here's a secure, simple pattern.

1. Users table

CREATE TABLE admins (
  id INT AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(190) NOT NULL UNIQUE,
  password_hash VARCHAR(255) NOT NULL,
  failed_logins INT NOT NULL DEFAULT 0,
  locked_until DATETIME NULL
);

2. Create a user with a hashed password

<?php
$hash = password_hash('a-long-unique-passphrase', PASSWORD_DEFAULT);
// INSERT the email and $hash using a prepared statement

Never store plain passwords or use md5()/sha1() for passwords.

3. Secure session settings

<?php
session_set_cookie_params([
    'httponly' => true,
    'secure'   => true,      // HTTPS only
    'samesite' => 'Lax',
]);
session_start();

4. The login handler

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'] ?? '')) exit('Invalid request');

    $email = trim($_POST['email'] ?? '');
    $pass  = $_POST['password'] ?? '';

    $stmt = $conn->prepare('SELECT id, password_hash, failed_logins, locked_until FROM admins WHERE email = ?');
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $user = $stmt->get_result()->fetch_assoc();

    if ($user && $user['locked_until'] && strtotime($user['locked_until']) > time()) {
        $error = 'Too many attempts. Try again later.';
    } elseif ($user && password_verify($pass, $user['password_hash'])) {
        session_regenerate_id(true);
        $_SESSION['admin_id'] = $user['id'];
        $conn->query('UPDATE admins SET failed_logins = 0, locked_until = NULL WHERE id = ' . (int)$user['id']);
        header('Location: /admin/dashboard.php');
        exit;
    } else {
        if ($user) {
            $stmt = $conn->prepare('UPDATE admins SET failed_logins = failed_logins + 1,
                locked_until = IF(failed_logins + 1 >= 5, NOW() + INTERVAL 15 MINUTE, NULL) WHERE id = ?');
            $stmt->bind_param('i', $user['id']);
            $stmt->execute();
        }
        $error = 'Invalid email or password.';
    }
}
$_SESSION['csrf'] = $_SESSION['csrf'] ?? bin2hex(random_bytes(32));

In the form, include <input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>">.

Notes:

  • The same error message for wrong email or password avoids revealing which emails exist
  • session_regenerate_id(true) prevents session fixation
  • The lockout slows brute-force attacks. See brute force attacks

5. Protect admin pages

<?php
session_start();
if (empty($_SESSION['admin_id'])) {
    header('Location: /admin/login.php');
    exit;
}

Put this at the top of every admin page (or in a shared include).

6. Logout

<?php
session_start();
$_SESSION = [];
session_destroy();
header('Location: /admin/login.php');

Extra hardening

  • HTTPS only
  • 2FA for admins (TOTP apps) on important systems
  • Log logins with IP and time
  • Rehash passwords with password_needs_rehash() when algorithms update

FAQs

Should I build my own login or use a framework?

Frameworks like Laravel include well-tested authentication. For small custom sites, the pattern above is solid.

How long should sessions last?

For admin panels, expire after inactivity (e.g. 30–60 minutes).

Was this article helpful?

Your answer helps us improve our guides

Share this article

Joboo Web

Web design, SEO & digital marketing team · Ludhiana, Punjab

Joboo Web has helped Indian businesses grow online since 2019 — building fast websites and running SEO, Google Ads and social campaigns for clients in 80+ cities. About us →

Keep reading

💬