The process of verifying that a user is who they claim to be — typically by validating credentials (password, token, certificate) and establishing a session or issuing a signed token for subsequent requests.
Explanation
Authentication answers 'who is this user?' — distinct from authorisation ('what can they do?'). PHP authentication typically uses one of three mechanisms: session-based (credentials validated, user ID stored in a server-side session, session ID sent as a cookie); token-based (JWT or opaque token issued on login, sent in Authorization header on subsequent requests, validated server-side); or OAuth/OIDC (delegated to a third party like Google, GitHub, or an identity provider). Critical implementation requirements: passwords must be hashed with password_hash() using PASSWORD_ARGON2ID or PASSWORD_BCRYPT (never MD5 or SHA); login forms must use HTTPS; brute-force protection (rate limiting, account lockout) must be in place; session IDs must be regenerated on privilege change (session_regenerate_id(true)) to prevent session fixation. Laravel Sanctum handles API token authentication; Laravel Breeze/Jetstream handle session-based authentication.
Common Misconception
✗ Storing the user ID in a session is all that is needed for authentication. Session-based authentication requires several additional security controls: the session must be started over HTTPS only (session.cookie_secure = true), the session cookie must be HTTP-only (session.cookie_httponly = true) to prevent JavaScript access, the session ID must be regenerated after login to prevent session fixation attacks, and the session must have a reasonable timeout. Missing any of these produces a working but exploitable authentication system.
Why It Matters
Authentication is the gateway to every protected resource in a PHP application. Mistakes in authentication implementation — weak password hashing, missing session regeneration, no brute-force protection, HTTP-only cookies absent — translate directly into account takeovers, data breaches, and credential stuffing attacks. The most common PHP authentication vulnerability is not using prepared statements in the credential check query (SQL injection bypass) or using MD5 for password hashing (crackable in seconds on a GPU). Both are easily avoided with password_hash() and PDO.
Common Mistakes
Using MD5 or SHA-1 for password hashing — use password_hash($pass, PASSWORD_ARGON2ID) exclusively.
Not regenerating the session ID after login — session_regenerate_id(true) prevents session fixation attacks.
Missing brute-force protection — without rate limiting, an attacker can try millions of passwords against any login endpoint.
Storing plaintext passwords or reversibly encrypted passwords — if the database is compromised, all passwords are exposed immediately.
Code Examples
✗ Vulnerable
// MD5 hashing + no session regeneration + SQL injection
$hash = md5($_POST['password']); // crackable in seconds
$user = $db->query("SELECT * FROM users WHERE email='{$_POST['email']}'
AND password='$hash'"); // SQL injectable
if ($user) {
$_SESSION['user_id'] = $user['id'];
// No session_regenerate_id — session fixation possible
}
✓ Fixed
// Secure authentication
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$_POST['email']]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password_hash'])) {
session_regenerate_id(true); // prevent session fixation
$_SESSION['user_id'] = $user['id'];
$_SESSION['logged_in_at'] = time();
// Redirect — never re-display login form on success
header('Location: /dashboard');
exit;
}
Use password_hash($pass, PASSWORD_ARGON2ID) to hash, password_verify($input, $hash) to check, session_regenerate_id(true) after successful login, and rate-limit login attempts