James Williams
Birmingham Newman University
jwilliams@staff.newman.ac.uk
3-hour session
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'];
?>
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!";
}
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;
}
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();
}
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;
}
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();
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";
}
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();
}
Time: 45 minutes
This task will help you master user authentication and session management
Take a break, ask questions, or catch up on the previous task.
Next: Secondary slides and Task 2
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;
}
}
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();
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";
}
}
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();
}
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();
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 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";
}
}
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();
}
Time: 45 minutes
This task will help you build a professional authentication system
E-commerce Core Features - Product catalogues, shopping cart, and order management