Skip to main content
Apartado de Salas implements a secure session-based authentication system with role-based access control (RBAC). The system uses PHP sessions and password hashing to protect user credentials.

Authentication Flow

The authentication system follows a standard login/logout pattern with session management:
1

User submits credentials

User provides username and password through the login form at /login.
2

Credentials validation

The system queries the database and verifies the password using password_verify().
// From app/models/user.php:14-47
public function authenticate(string $username, string $password)
{
    $sql = "SELECT id, username, email, password, role 
            FROM users WHERE username = :username LIMIT 1";
    
    $user = $stmt->fetch();
    
    if (!$user || !password_verify($password, $user['password'])) {
        return false;
    }
    
    unset($user['password']); // Never return password
    return $user;
}
3

Session creation

On successful authentication, a session is created with user data stored in $_SESSION['user'].
// From app/Helpers/Session.php:18-22
public static function create(array $userData): void
{
    self::start();
    $_SESSION['user'] = $userData;
}
4

Redirect to dashboard

User is redirected to /dashboard after successful login.

Session Management

The Session helper class provides static methods for managing user sessions throughout the application.

Core Session Methods

Initializes a PHP session if one doesn’t already exist.
// From app/Helpers/Session.php:8-13
public static function start(): void
{
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
}
Checks if a user session exists.
// From app/Helpers/Session.php:27-31
public static function isActive(): bool
{
    self::start();
    return isset($_SESSION['user']);
}
Completely destroys the current session.
// From app/Helpers/Session.php:36-41
public static function destroy(): void
{
    self::start();
    session_unset();
    session_destroy();
}

Flash Messages

The session system includes support for one-time flash messages:
// From app/Helpers/Session.php:46-50
public static function setFlash(string $key, string $message): void
{
    self::start();
    $_SESSION['flash'][$key] = $message;
}
Usage:
Session::setFlash('success', 'Reservación creada correctamente.');
Session::setFlash('error', 'Datos incompletos.');

Authentication Helpers

The Auth class provides convenient methods for authentication checks and access control.

Checking Authentication Status

// From app/Helpers/Auth.php:10-13
public static function check(): bool
{
    return Session::isActive();
}

Getting Current User

// From app/Helpers/Auth.php:17-20
public static function user(): ?array
{
    return $_SESSION['user'] ?? null;
}
Returns: Array with user data (id, username, email, role) or null if not authenticated.

Role-Based Access Control

Apartado de Salas implements RBAC with two primary roles: user and admin.

Role Verification

// From app/Helpers/Auth.php:34-41
public static function hasRole(string $role): bool
{
    if (!self::check()) {
        return false;
    }
    
    return ($_SESSION['user']['role'] ?? null) === $role;
}
Usage:
if (Auth::hasRole('admin')) {
    // Show admin features
}

Require Login

Force users to authenticate before accessing a resource:
// From app/Helpers/Auth.php:24-30
public static function requireLogin(): void
{
    if (!self::check()) {
        header('Location: ' . BASE_URL . '/login');
        exit;
    }
}
Usage Example: All reservation operations require authentication:
// From app/controllers/ReservationController.php:17
public function create(): void
{
    Auth::requireLogin();
    // ...
}

Logout Process

The logout process completely destroys the session and regenerates the session ID for security:
// From app/controllers/AuthController.php:53-70
public function logout(): void
{
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    
    session_unset();        // Clear all session variables
    session_destroy();       // Destroy the session
    session_regenerate_id(true); // Regenerate session ID
    
    header('Location: ' . BASE_URL . '/login');
    exit;
}
Always use session_regenerate_id(true) after logout to prevent session fixation attacks.

Security Best Practices

The authentication system implements several security measures:
1

Password Hashing

Passwords are hashed using PHP’s password_hash() and verified with password_verify().
// Never store plain text passwords
password_verify($password, $user['password'])
2

Password Removal

Password hashes are never included in session data or returned to the client.
unset($user['password']); // From user.php:44
3

Session Security

Session ID is regenerated on logout to prevent session fixation attacks.
4

Access Control

Role-based checks prevent unauthorized access to admin functions.

Common Authentication Patterns

// No authentication required
public function showLogin(): void
{
    if (Session::isActive()) {
        header('Location: ' . BASE_URL . '/dashboard');
        exit;
    }
    // Show login page
}

User Data Structure

The authenticated user object stored in $_SESSION['user'] contains:
[
    'id' => 1,
    'username' => 'john_doe',
    'email' => '[email protected]',
    'role' => 'admin' // or 'user'
]
The password hash is never included in the session data for security reasons.

Build docs developers (and LLMs) love