H M < >
CMU529: Advanced Web Development - Session 8

Session Management & User Authentication

Full-stack Web Development with PHP and MySQL

James Williams

Birmingham Newman University

jwilliams@staff.newman.ac.uk

3-hour session

Learning Objectives

  • Implement user registration and login systems
  • Manage user sessions securely
  • Create authentication and authorization
  • Handle password security and recovery
  • Build protected user areas

Session Basics

Starting Sessions:
<?php
// Start session at beginning of script
session_start();
// Store data in session
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'john_doe';
$_SESSION['logged_in'] = true;
// Access session data
echo "Welcome " . $_SESSION['username'];
?>
  • Sessions store data on server
  • Session ID stored in browser cookie
  • Data persists across page requests

User Registration

Registration Process:
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $username = trim($_POST['username']);
  $email = trim($_POST['email']);
  $password = $_POST['password'];
  // Hash password
  $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
  // Insert user into database
  $stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
  $stmt->execute([$username, $email, $hashedPassword]);
  echo "Registration successful!";
}
  • Always hash passwords
  • Validate input data
  • Check for duplicate emails

User Login

Login Verification:
function authenticateUser($email, $password) {
  global $pdo;
  $stmt = $pdo->prepare("SELECT id, username, password FROM users WHERE email = ?");
  $stmt->execute([$email]);
  $user = $stmt->fetch();
  if ($user && password_verify($password, $user['password'])) {
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['username'] = $user['username'];
    $_SESSION['logged_in'] = true;
    return true;
  }
  return false;
}
  • Use password_verify() for comparison
  • Store user data in session
  • Return boolean for success/failure

Session Management

Session Functions:
// Check if user is logged in
function isLoggedIn() {
  return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true;
}
// Logout function
function logout() {
  session_start();
  session_destroy();
  header("Location: login.php");
  exit();
}
// Protect pages
if (!isLoggedIn()) {
  header("Location: login.php");
  exit();
}
  • Check login status on protected pages
  • Destroy session on logout
  • Redirect unauthorized users

Password Security

Password Validation:
function validatePassword($password) {
  $errors = [];
  if (strlen($password) < 8) {
    $errors[] = "Password must be at least 8 characters";
  }
  if (!preg_match("/[A-Z]/", $password)) {
    $errors[] = "Password must contain uppercase letter";
  }
  if (!preg_match("/[0-9]/", $password)) {
    $errors[] = "Password must contain number";
  }
  return $errors;
}
  • Enforce strong password requirements
  • Use regex for pattern matching
  • Return array of validation errors

Password Reset

Reset Token System:
// Generate reset token
$token = bin2hex(random_bytes(32));
$expires = date('Y-m-d H:i:s', strtotime('+1 hour'));
// Store token in database
$stmt = $pdo->prepare("INSERT INTO password_resets (email, token, expires) VALUES (?, ?, ?)");
$stmt->execute([$email, $token, $expires]);
// Send email with reset link
$resetLink = "https://example.com/reset.php?token=" . $token;
mail($email, "Password Reset", "Click here to reset: " . $resetLink);
// Verify token
$stmt = $pdo->prepare("SELECT * FROM password_resets WHERE token = ? AND expires > NOW()");
$stmt->execute([$token]);
$reset = $stmt->fetch();
  • Generate secure random tokens
  • Set expiration times
  • Send reset links via email

User Profiles

Profile Management:
// Get user profile
$userId = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);
$user = $stmt->fetch();
// Update profile
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $firstName = trim($_POST['first_name']);
  $lastName = trim($_POST['last_name']);
  $phone = trim($_POST['phone']);
  $stmt = $pdo->prepare("UPDATE users SET first_name = ?, last_name = ?, phone = ? WHERE id = ?");
  $stmt->execute([$firstName, $lastName, $phone, $userId]);
  echo "Profile updated successfully";
}
  • Display user information
  • Allow profile updates
  • Validate input data

Authorization

Role-Based Access:
// Check user role
function hasRole($role) {
  global $pdo;
  $userId = $_SESSION['user_id'];
  $stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?");
  $stmt->execute([$userId]);
  $user = $stmt->fetch();
  return $user['role'] === $role;
}
// Protect admin pages
if (!hasRole('admin')) {
  header("Location: access-denied.php");
  exit();
}
  • Check user permissions
  • Restrict access to features
  • Redirect unauthorized users

Task 1: User Authentication System

Instructions:

  1. Create a complete user authentication system with:
    • User registration form with validation
    • Login form with authentication
    • Session management and security
    • Password reset functionality
    • User profile management
  2. Implement password security measures
  3. Add CSRF protection
  4. Create protected user areas
  5. Test all authentication flows

Time: 45 minutes

This task will help you master user authentication and session management

Break Time

15 Minutes

Take a break, ask questions, or catch up on the previous task.

Next: Secondary slides and Task 2

Remember Me Functionality

Persistent Login:
// Set remember me cookie
if (isset($_POST['remember_me'])) {
  $token = bin2hex(random_bytes(32));
  $expires = time() + (30 * 24 * 60 * 60); // 30 days
  // Store token in database
  $stmt = $pdo->prepare("INSERT INTO remember_tokens (user_id, token, expires) VALUES (?, ?, ?)");
  $stmt->execute([$userId, $token, date('Y-m-d H:i:s', $expires)]);
  // Set cookie
  setcookie('remember_token', $token, $expires, '/', '', true, true);
}
// Check remember me token
if (isset($_COOKIE['remember_token'])) {
  $token = $_COOKIE['remember_token'];
  $stmt = $pdo->prepare("SELECT user_id FROM remember_tokens WHERE token = ? AND expires > NOW()");
  $stmt->execute([$token]);
  $result = $stmt->fetch();
  if ($result) {
    $_SESSION['user_id'] = $result['user_id'];
    $_SESSION['logged_in'] = true;
  }
}

Session Security

Security Measures:
// Secure session configuration
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_strict_mode', 1);
// Regenerate session ID
if (!isset($_SESSION['initialized'])) {
  session_regenerate_id(true);
  $_SESSION['initialized'] = true;
}
// Check session timeout
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > 1800)) {
  session_unset();
  session_destroy();
  header("Location: login.php");
  exit();
}
$_SESSION['last_activity'] = time();

Two-Factor Authentication

SMS Verification:
// Generate verification code
$verificationCode = sprintf("%06d", mt_rand(0, 999999));
$_SESSION['verification_code'] = $verificationCode;
$_SESSION['verification_time'] = time();
// Send SMS (mock implementation)
$message = "Your verification code is: " . $verificationCode;
// sendSMS($phone, $message);
// Verify code
if (isset($_POST['verification_code'])) {
  $inputCode = $_POST['verification_code'];
  $storedCode = $_SESSION['verification_code'];
  $verificationTime = $_SESSION['verification_time'];
  if ($inputCode === $storedCode && (time() - $verificationTime) < 300) {
    $_SESSION['two_factor_verified'] = true;
    echo "Verification successful";
  } else {
    echo "Invalid or expired code";
  }
}

Account Lockout

Failed Login Protection:
// Track failed login attempts
function recordFailedLogin($email) {
  global $pdo;
  $stmt = $pdo->prepare("INSERT INTO failed_logins (email, ip_address, timestamp) VALUES (?, ?, NOW())");
  $stmt->execute([$email, $_SERVER['REMOTE_ADDR']]);
}
// Check if account is locked
function isAccountLocked($email) {
  global $pdo;
  $stmt = $pdo->prepare("SELECT COUNT(*) FROM failed_logins WHERE email = ? AND timestamp > DATE_SUB(NOW(), INTERVAL 15 MINUTE)");
  $stmt->execute([$email]);
  $failedAttempts = $stmt->fetchColumn();
  return $failedAttempts >= 5;
}
// Check before login
if (isAccountLocked($email)) {
  echo "Account temporarily locked. Try again in 15 minutes.";
  exit();
}

User Activity Logging

Activity Tracking:
function logUserActivity($userId, $action, $details = '') {
  global $pdo;
  $stmt = $pdo->prepare("INSERT INTO user_activity (user_id, action, details, ip_address, timestamp) VALUES (?, ?, ?, ?, NOW())");
  $stmt->execute([$userId, $action, $details, $_SERVER['REMOTE_ADDR']]);
}
// Log login
logUserActivity($userId, 'login', 'User logged in successfully');
// Log profile update
logUserActivity($userId, 'profile_update', 'Updated personal information');
// Log password change
logUserActivity($userId, 'password_change', 'Password changed successfully');
// Get user activity
$stmt = $pdo->prepare("SELECT * FROM user_activity WHERE user_id = ? ORDER BY timestamp DESC LIMIT 10");
$stmt->execute([$userId]);
$activities = $stmt->fetchAll();

Social Login Integration

OAuth Implementation:
// Google OAuth callback
if (isset($_GET['code'])) {
  $code = $_GET['code'];
  $clientId = 'your_google_client_id';
  $clientSecret = 'your_google_client_secret';
  // Exchange code for token
  $tokenUrl = 'https://oauth2.googleapis.com/token';
  $data = [
    'code' => $code,
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'redirect_uri' => 'https://yoursite.com/callback.php',
    'grant_type' => 'authorization_code'
  ];
  // Get user info from Google
  $userInfo = getUserInfoFromGoogle($accessToken);
  // Create or login user
  handleSocialLogin($userInfo);
}

Email Verification

Email Confirmation:
// Generate verification token
$verificationToken = bin2hex(random_bytes(32));
$stmt = $pdo->prepare("UPDATE users SET email_verified = 0, verification_token = ? WHERE id = ?");
$stmt->execute([$verificationToken, $userId]);
// Send verification email
$verificationLink = "https://example.com/verify.php?token=" . $verificationToken;
$to = $email;
$subject = "Verify Your Email Address";
$message = "Click the following link to verify your email: " . $verificationLink;
$headers = "From: noreply@example.com";
mail($to, $subject, $message, $headers);
// Verify email
if (isset($_GET['token'])) {
  $token = $_GET['token'];
  $stmt = $pdo->prepare("UPDATE users SET email_verified = 1, verification_token = NULL WHERE verification_token = ?");
  $stmt->execute([$token]);
  if ($stmt->rowCount() > 0) {
    echo "Email verified successfully";
  }
}

Session Hijacking Protection

Security Measures:
// Store user agent in session
if (!isset($_SESSION['user_agent'])) {
  $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
}
// Check for session hijacking
if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
  session_unset();
  session_destroy();
  header("Location: login.php?error=hijacking");
  exit();
}
// Store IP address
if (!isset($_SESSION['ip_address'])) {
  $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
}
// Check IP changes
if ($_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
  session_unset();
  session_destroy();
  header("Location: login.php?error=ip_change");
  exit();
}

Task 2: Advanced Authentication System

Instructions:

  1. Build an advanced authentication system with:
    • Two-factor authentication (SMS/Email)
    • Remember me functionality
    • Account lockout protection
    • User activity logging
    • Email verification system
    • Social login integration
  2. Implement session security measures
  3. Add comprehensive error handling
  4. Create admin user management
  5. Test all security features

Time: 45 minutes

This task will help you build a professional authentication system

Session Summary

  • User authentication is essential for web applications
  • Session management maintains user state
  • Password security protects user accounts
  • Two-factor authentication adds extra security
  • Account lockout prevents brute force attacks
  • Activity logging helps monitor user behavior
  • Email verification ensures valid user accounts
  • Social login provides convenient authentication

Next Session:

E-commerce Core Features - Product catalogues, shopping cart, and order management