Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- // Claude Sonnet
- /**
- * @file AuthController.php
- * @description Handles login requests securely with session, CSRF, and redirect handling.
- * This controller processes user login and manages session regeneration and flash errors.
- *
- * @version 1.0.0
- * @since 2025-07-29
- * @author Barrac0de
- */
- declare(strict_types=1);
- namespace App\Auth;
- use PDO;
- require_once __DIR__ . '/../../config.php';
- require_once __DIR__ . '/AuthService.php';
- class AuthController
- {
- /** @var PDO */
- private $pdo;
- /** @var AuthService */
- private $authService;
- /** @var int */
- private $sessionTimeout = 3600; // 1 hour
- /**
- * Constructor
- *
- * @param PDO $pdo Database connection
- */
- public function __construct(PDO $pdo)
- {
- $this->pdo = $pdo;
- $this->authService = new AuthService($pdo);
- // Enforce strict session ID handling
- ini_set('session.use_strict_mode', '1');
- if (session_status() === PHP_SESSION_NONE) {
- ini_set('session.cookie_httponly', '1');
- ini_set('session.cookie_secure', '1');
- ini_set('session.cookie_samesite', 'Lax');
- session_start();
- }
- // Security headers
- header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
- header('X-Frame-Options: DENY');
- header('X-Content-Type-Options: nosniff');
- header('Referrer-Policy: no-referrer');
- header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self';");
- }
- /**
- * Handle the login request
- */
- public function handleRequest()
- {
- // Redirect if database connection failed
- if (!isset($this->pdo) || !($this->pdo instanceof PDO)) {
- http_response_code(500);
- exit('Database connection failed.');
- }
- // Check session timeout
- $this->checkSessionTimeout();
- if ($_SERVER['REQUEST_METHOD'] === 'GET') {
- $this->handleGetRequest();
- } else {
- $this->handlePostRequest();
- }
- }
- /**
- * Handle GET requests for the login page
- */
- private function handleGetRequest()
- {
- // Redirect if already authenticated
- if (isset($_SESSION['user_id'])) {
- header('Location: ' . BASE_PATH . 'index');
- exit;
- }
- // Flash error and old username
- $error = $_SESSION['login_error'] ?? '';
- $oldUsername = $_SESSION['old_username'] ?? '';
- unset($_SESSION['login_error'], $_SESSION['old_username']);
- // CSRF token
- if (empty($_SESSION['csrf_token'])) {
- $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
- }
- // Expose view variables
- require __DIR__ . '/../../login.php';
- exit;
- }
- /**
- * Handle POST requests for login form submission
- */
- private function handlePostRequest()
- {
- // CSRF protection
- $csrfToken = filter_input(INPUT_POST, 'csrf_token', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? '';
- if (empty($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $csrfToken)) {
- $this->authService->bounce('Invalid CSRF token.');
- }
- // Input sanitization
- $username = trim((string)filter_input(INPUT_POST, 'username', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
- $password = (string)filter_input(INPUT_POST, 'password', FILTER_UNSAFE_RAW);
- // Authenticate user
- $user = $this->authService->authenticate($username, $password);
- if ($user) {
- // Login success
- session_regenerate_id(true);
- $_SESSION['user_id'] = $user['id'];
- // Rotate CSRF token
- $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
- header('Location: ' . BASE_PATH . 'index');
- exit;
- }
- }
- /**
- * Check for session timeout and handle accordingly
- */
- private function checkSessionTimeout()
- {
- $_SESSION['last_activity'] = time();
- if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $this->sessionTimeout) {
- session_unset();
- session_destroy();
- header('Location: ' . BASE_PATH . 'login?timeout=1');
- exit;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment