Sessions & Cookies
Info: Automatic Encryption: All session data and cookies are automatically encrypted using XChaCha20-Poly1305 AEAD cipher. No middleware configuration needed.
Overview
Larafony's session and cookie system provides:
-
Automatic Encryption - All data encrypted with XChaCha20-Poly1305
-
Dual Storage - File-based and database-backed session handlers
-
PSR-20 Clock Integration - Testable time-based operations
-
Secure Defaults - HttpOnly, Secure (HTTPS), SameSite protection
-
SessionHandlerInterface - Standard PHP session handler implementation
-
Transparent API - Simple get/set interface, encryption happens automatically
Session Management
Basic Session Usage
use Larafony\Framework\Storage\Session\SessionManager;
// Create and start session (auto-selects handler from config)
$session = SessionManager::create();
// Store data (automatically encrypted)
$session->set('user_id', 42);
$session->set('cart', ['item1', 'item2', 'item3']);
$session->set('preferences', [
'theme' => 'dark',
'language' => 'en'
]);
// Retrieve data (automatically decrypted)
$userId = $session->get('user_id'); // 42
$cart = $session->get('cart', []); // ['item1', 'item2', 'item3']
// Check existence
if ($session->has('user_id')) {
// User is logged in
}
// Get all session data
$allData = $session->all();
// Remove specific item
$session->remove('cart');
// Clear all session data
$session->clear();
// Get session ID
$sessionId = $session->getId();
Session Security
// Regenerate session ID (best practice after login)
$session->regenerateId(deleteOldSession: true);
// Destroy session (logout)
$session->destroy();
Success: Security Best Practice: Always regenerate the session ID after authentication to prevent session fixation attacks.
Session Storage Handlers
File-Based Sessions
Default handler, stores encrypted session data as files:
// config/session.php
return [
'handler' => \Larafony\Framework\Storage\Session\Handlers\FileSessionHandler::class,
'path' => sys_get_temp_dir() . '/sessions',
// or: storage_path('framework/sessions')
];
Features:
-
✅ Simple, no database required
-
✅ Automatic garbage collection of expired sessions
-
✅ Good for single-server applications
-
❌ Not suitable for load-balanced environments
Database-Backed Sessions
Recommended for production and multi-server setups:
// config/session.php
return [
'handler' => \Larafony\Framework\Storage\Session\Handlers\DatabaseSessionHandler::class,
];
Features:
-
✅ Scalable - works with load balancers
-
✅ Tracks user IP, user agent, user ID
-
✅ Automatic expiration checking
-
✅ ORM integration with property hooks
-
✅ Indexed queries for performance
Setup Database Sessions
Step 1: Generate migration
php bin/console table:session
Step 2: Run migration
php bin/console migrate
Step 3: Configure handler in config/session.php
return [
'handler' => \Larafony\Framework\Storage\Session\Handlers\DatabaseSessionHandler::class,
'cookie_params' => [
'lifetime' => 7200, // 2 hours
'path' => '/',
'domain' => '',
'secure' => true, // HTTPS only
'httponly' => true, // No JavaScript access
'samesite' => 'Strict', // CSRF protection
],
];
Database Schema
The sessions table stores:
CREATE TABLE sessions (
id VARCHAR(255) PRIMARY KEY, -- Session ID
payload TEXT NOT NULL, -- Encrypted session data
last_activity INT NOT NULL, -- Unix timestamp
user_ip VARCHAR(45) NULL, -- IPv4 or IPv6
user_agent TEXT NULL, -- Browser info
user_id BIGINT UNSIGNED NULL, -- Linked user (if authenticated)
INDEX idx_last_activity (last_activity),
INDEX idx_user_id (user_id)
);
Cookie Management
Basic Cookie Usage
use Larafony\Framework\Storage\CookieManager;
use Larafony\Framework\Storage\CookieOptions;
$cookies = new CookieManager();
// Set encrypted cookie with defaults
$cookies->set('user_preferences', [
'theme' => 'dark',
'language' => 'en',
'notifications' => true
]);
// Retrieve and decrypt automatically
$preferences = $cookies->get('user_preferences');
// Returns: ['theme' => 'dark', 'language' => 'en', 'notifications' => true]
// Get with default value
$settings = $cookies->get('settings', ['default' => 'value']);
// Get all cookies (decrypted)
$allCookies = $cookies->all();
// Remove cookie
$cookies->remove('user_preferences');
Cookie Options
use Larafony\Framework\Storage\CookieOptions;
// Custom cookie options
$options = new CookieOptions(
expires: time() + 86400, // 24 hours from now
path: '/admin', // Available only under /admin
domain: '.example.com', // Available on all subdomains
secure: true, // HTTPS only
httponly: true, // No JavaScript access
samesite: 'Strict' // Strict CSRF protection
);
$cookies->set('admin_token', 'secret_value', $options);
Secure Defaults
CookieOptions provides secure defaults automatically:
// Default options (without parameters):
new CookieOptions()
// Equivalent to:
new CookieOptions(
expires: time() + 3600, // 1 hour
path: '/',
domain: '',
secure: (HTTPS detected), // Auto-detects HTTPS
httponly: true, // Always true by default
samesite: 'Lax' // Balanced security
)
Warning: Production Tip: Always use
secure: trueandsamesite: 'Strict'in production to maximize security.
Session Configuration
Complete Configuration Example
// config/session.php
use Larafony\Framework\Config\Environment\EnvReader;
use Larafony\Framework\Storage\Session\Handlers\DatabaseSessionHandler;
use Larafony\Framework\Storage\Session\Handlers\FileSessionHandler;
return [
// Session handler: file or database
'handler' => EnvReader::read('SESSION_DRIVER') === 'database'
? DatabaseSessionHandler::class
: FileSessionHandler::class,
// File storage path (for FileSessionHandler)
'path' => EnvReader::read('SESSION_PATH', sys_get_temp_dir() . '/sessions'),
// Cookie configuration
'cookie_params' => [
'lifetime' => (int) EnvReader::read('SESSION_LIFETIME', '7200'),
'path' => EnvReader::read('SESSION_PATH_COOKIE', '/'),
'domain' => EnvReader::read('SESSION_DOMAIN', ''),
'secure' => EnvReader::read('SESSION_SECURE_COOKIE') === 'true'
|| (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
'httponly' => EnvReader::read('SESSION_HTTP_ONLY', 'true') === 'true',
'samesite' => EnvReader::read('SESSION_SAME_SITE', 'Lax'),
],
];
Environment Variables
# .env file
# Session driver: file or database
SESSION_DRIVER=database
# Session lifetime (seconds)
SESSION_LIFETIME=7200
# File storage path (if using file driver)
SESSION_PATH=/var/www/storage/sessions
# Cookie settings
SESSION_PATH_COOKIE=/
SESSION_DOMAIN=
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=Strict
How Encryption Works
Session Encryption
Sessions are encrypted at the storage layer:
// SessionSecurity class (used by both handlers)
class SessionSecurity
{
public function encrypt(string $data): string
{
$encryptor = new EncryptionService();
return $encryptor->encrypt($data);
}
public function decrypt(string $encrypted): string
{
$encryptor = new EncryptionService();
return $encryptor->decrypt($encrypted);
}
}
// FileSessionHandler writes encrypted data
public function write(string $id, string $data): bool
{
$encrypted = $this->security->encrypt($data);
file_put_contents($this->getFilePath($id), $encrypted);
return true;
}
// DatabaseSessionHandler writes encrypted data
public function write(string $id, string $data): bool
{
$encrypted = $this->security->encrypt($data);
$session->payload = $encrypted;
$session->save();
return true;
}
Cookie Encryption
Cookies are transparently encrypted/decrypted:
// CookieManager automatically encrypts
public function set(string $name, mixed $value, CookieOptions $options): void
{
$encrypted = new EncryptionService()->encrypt($value);
setcookie($name, $encrypted, $options->toArray());
}
// CookieManager automatically decrypts
public function get(string $name, mixed $default = null): mixed
{
$value = $_COOKIE[$name] ?? null;
if ($value === null) {
return $default;
}
return new EncryptionService()->decrypt($value);
}
Comparison with Other Frameworks
| Feature | Larafony | Laravel | Symfony |
|---|---|---|---|
| Session Encryption | Automatic | Optional (middleware) | Manual (bundles) |
| Cookie Encryption | Automatic | Middleware required | Manual (bundles) |
| Storage Handlers | File, Database | File, DB, Redis, Array | File, PDO, Redis, Memcached |
| Configuration | Simple config file | .env + config files | YAML/PHP config |
| Cipher | XChaCha20-Poly1305 | AES-256-CBC + HMAC | Varies |
| Clock Integration | PSR-20 | Carbon (not PSR) | DateTime/Clock
Use CasesUser Authentication
Shopping Cart
Remember Me Cookie
Best Practices
Next Steps
Learn MoreThis implementation is explained in detail with step-by-step tutorials, tests, and best practices at masterphp.eu Demo App: See encrypted sessions and cookies in production with file and database storage handlers. The demo application showcases automatic encryption, PSR-20 clock integration, and secure cookie defaults with HttpOnly and SameSite protection. |