Sessions

Flexagon sessions serialize model objects into encrypted cookies rather than server-side files. Because there is no shared session store, horizontally scaling across multiple web servers requires no additional session-storage configuration.

Configuration

// application/_Config.php
_Global::$SESSION_AUTO_START      = true;
_Global::$SESSION_ENCRYPTION_STRING = Env::required('SESSION_ENCRYPTION_STRING');   // from .env.php
_Global::$SESSION_DOMAIN          = '.example.com';
_Global::$SESSION_TIMEOUT_SECONDS = 86400;

// Cookie security attributes — the defaults are already secure and usually do not need to be changed.
_Global::$SESSION_COOKIE_SECURE   = null;    // null = automatically enabled for HTTPS requests
_Global::$SESSION_COOKIE_HTTPONLY = true;    // prevent JavaScript from accessing the session cookie
_Global::$SESSION_COOKIE_SAMESITE = 'Lax';

Session cookies carry authentication state, so HttpOnly and SameSite=Lax are enabled by default, and Secure is added automatically for HTTPS requests. HTTPS detection checks $_SERVER['HTTPS'], port 443, and then X-Forwarded-Proto.

Session Model and DAO

<?php
namespace Session;

use _Flexagon\Base\BaseModel;

class SessionUserModel extends BaseModel {
    private string  $role     = 'USER';
    private ?string $username = '';
    private ?string $email    = '';
    // getters / setters ...
}
<?php
namespace Session;

use _Flexagon\Base\BaseSessionDAO;

class SessionDAO extends BaseSessionDAO {}

Usage

// Log in
$sessionUser = new SessionUserModel();
$sessionUser->setUsername($user->getUsername());
$sessionUser->setRole('ADMIN');

$sessionDAO = new SessionDAO();
$sessionDAO->makeSession($sessionUser);

// Log out
$sessionDAO->cleanSession();

When $SESSION_AUTO_START is enabled, the session is restored during bootstrap and exposed in two locations.

_Global::$SESSION_MODEL;        // always available here
_Global::$SESSION_USER_MODEL;   // class-name-based global (see below)

The second form is derived by converting the model class name to UPPER_SNAKE_CASE (SessionUserModel → SESSION_USER_MODEL). To access it with a type hint, declare the corresponding static property in _Global in advance.

class _Global extends BaseGlobal {
    public static ?\Session\SessionUserModel $SESSION_USER_MODEL = null;
}

A common pattern is to perform authorization checks in _prepare.php.

<?php
// public/_prepare.php
if (str_starts_with(_Global::$URL_PARAM->filePath, 'admin/')) {
    if (_Global::$SESSION_USER_MODEL?->getRole() !== 'ADMIN') {
        \_Flexagon\Libs\HtmlUtil::redirectPage('/login');
    }
}

Note: A session-model property marked with @encrypt is encrypted twice inside the cookie. Because the entire session cookie is already encrypted with $SESSION_ENCRYPTION_STRING, the additional annotation is usually unnecessary.