From ce1d13e8626235a38dc540f7686a6b993d5d79c7 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Thu, 11 Sep 2025 10:41:30 -0500 Subject: [PATCH] add cookie documentation --- EXAMPLES.md | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-- README.md | 34 ++++++++++++- 2 files changed, 168 insertions(+), 5 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index b37fe76..e8976dc 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -312,6 +312,139 @@ $session->clear(); // Clear data but keep session active $all = $session->all(); // Get all session data ``` +## Cookies Examples + +```php +// Cookie management is automatically available through Context +$context->cookie; // Access the Cookies instance + +// Basic cookie operations +$context->cookie->set('name', 'value'); // Session cookie +$context->cookie->get('name', 'default'); // Get cookie value +$context->cookie->has('name'); // Check if cookie exists +$context->cookie->delete('name'); // Delete cookie + +// Cookie with specific lifetime +$context->cookie->setForDays('remember_me', 'token', 30); // 30 days +$context->cookie->setForHours('temp_data', 'value', 2); // 2 hours +$context->cookie->setForMinutes('flash', 'quick', 5); // 5 minutes +$context->cookie->forever('permanent', 'value'); // 5 years + +// Session cookie (expires when browser closes) +$context->cookie->setSession('session_data', 'value'); + +// Custom lifetime in seconds +$context->cookie->setWithLifetime('custom', 'value', 7200); // 2 hours + +// Cookie with options +$context->cookie->set('secure_cookie', 'value', [ + 'expires' => time() + 3600, + 'path' => '/admin', + 'domain' => '.example.com', + 'secure' => true, + 'httponly' => true, + 'samesite' => 'Strict' +]); + +// Signed cookies (integrity verification) +$secret = 'your-secret-key'; +$context->cookie->setSigned('signed_data', 'sensitive', $secret); +$value = $context->cookie->getSigned('signed_data', $secret); // Returns null if tampered + +// Encrypted cookies (for sensitive data) +$key = 'your-encryption-key-32-chars-long!!'; +$context->cookie->setEncrypted('encrypted_data', 'very_sensitive', $key); +$value = $context->cookie->getEncrypted('encrypted_data', $key); // Returns null if corrupted + +// Get all cookies +$allCookies = $context->cookie->all(); + +// Clear all cookies +$context->cookie->clear(); + +// Configure cookie defaults for the application +$app = new Web(debug: true, cookieDefaults: [ + 'path' => '/', + 'domain' => '.example.com', + 'secure' => true, + 'httponly' => true, + 'samesite' => 'Lax' +]); + +// Or set defaults later +$context->cookie->setDefaults([ + 'secure' => true, + 'httponly' => true +]); + +// Using cookies in route handlers +$app->get('/set-preference', function(Context $context) { + $theme = $context->query('theme', 'light'); + $context->cookie->setForDays('user_theme', $theme, 365); + return ['message' => 'Theme preference saved']; +}); + +$app->get('/get-preference', function(Context $context) { + $theme = $context->cookie->get('user_theme', 'light'); + return ['theme' => $theme]; +}); + +// Using cookies with authentication +$app->post('/login', function(Context $context) use ($auth) { + // ... validate credentials ... + + if ($context->input('remember')) { + // Auth class uses Cookies internally for remember tokens + $auth->login($userData, true); + } else { + $auth->login($userData, false); + } + + // Set additional preference cookies + $context->cookie->setForDays('last_login', date('Y-m-d'), 30); + + return ['message' => 'Logged in successfully']; +}); + +// Tracking with signed cookies +$app->use(function(Context $context, callable $next) { + $secret = 'tracking-secret'; + $visitCount = (int)$context->cookie->getSigned('visit_count', $secret, '0'); + $visitCount++; + $context->cookie->setSigned('visit_count', (string)$visitCount, $secret); + $context->set('visit_count', $visitCount); + $next(); +}); + +// Storing user preferences securely +$app->post('/preferences', function(Context $context) { + $preferences = $context->only(['theme', 'language', 'timezone']); + $key = 'encryption-key-must-be-32-chars!'; + + // Store encrypted preferences + $context->cookie->setEncrypted( + 'user_prefs', + json_encode($preferences), + $key, + ['expires' => time() + 31536000] // 1 year + ); + + return ['message' => 'Preferences saved securely']; +}); + +$app->get('/preferences', function(Context $context) { + $key = 'encryption-key-must-be-32-chars!'; + $encrypted = $context->cookie->getEncrypted('user_prefs', $key); + + if ($encrypted) { + $preferences = json_decode($encrypted, true); + return ['preferences' => $preferences]; + } + + return ['preferences' => null]; +}); +``` + ## Validation Examples ```php @@ -346,10 +479,10 @@ Validator::extend('custom', function($value, $parameters, $data) { ## Authentication Examples ```php -$auth = new Auth($session, [ +// Auth automatically uses Cookies for remember tokens +$auth = new Auth($session, $context->cookie, [ 'cookie_name' => 'remember_token', - 'cookie_lifetime' => 2592000, // 30 days - 'cookie_secure' => true + 'cookie_lifetime' => 2592000 // 30 days ]); // Authentication diff --git a/README.md b/README.md index ed4320a..f3ace55 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,15 @@ Session management with security features. - CSRF token generation and validation - Session lifecycle management +### Cookies +Comprehensive cookie management with security features. +- Consistent cookie handling across the application +- Convenient lifetime methods (sessions, days, hours, minutes) +- Signed cookies for integrity verification +- Encrypted cookies for sensitive data +- Configurable defaults for all cookie operations +- Automatic integration with Context and Response + ### Validator Input validation with 20+ built-in rules. - Chainable validation rules (`required|email|min:6`) @@ -100,7 +109,7 @@ Comprehensive error and exception handling. ### Web Class ```php -new Web(bool $debug = false) +new Web(bool $debug = false, array $cookieDefaults = []) use(callable $middleware): self get|post|put|patch|delete|head(string $route, callable $handler): self group(string $prefix, callable $callback): self @@ -150,9 +159,30 @@ validateRequest(array $rules, array $messages = []): Validator ### Validator Rules `required`, `email`, `url`, `alpha`, `alphaNum`, `numeric`, `integer`, `float`, `boolean`, `array`, `json`, `date`, `min:n`, `max:n`, `between:min,max`, `length:n`, `in:a,b,c`, `notIn:a,b,c`, `regex:/pattern/`, `confirmed`, `unique:table,column`, `exists:table,column` +### Cookies Class +```php +new Cookies(array $defaults = []) +set(string $name, string $value, array $options = []): bool +get(string $name, ?string $default = null): ?string +has(string $name): bool +delete(string $name, array $options = []): bool +setSession(string $name, string $value, array $options = []): bool +setWithLifetime(string $name, string $value, int $lifetime, array $options = []): bool +setForDays(string $name, string $value, int $days, array $options = []): bool +setForHours(string $name, string $value, int $hours, array $options = []): bool +setForMinutes(string $name, string $value, int $minutes, array $options = []): bool +forever(string $name, string $value, array $options = []): bool +all(): array +clear(): void +setSigned(string $name, string $value, string $secret, array $options = []): bool +getSigned(string $name, string $secret, ?string $default = null): ?string +setEncrypted(string $name, string $value, string $key, array $options = []): bool +getEncrypted(string $name, string $key, ?string $default = null): ?string +``` + ### Auth Class ```php -new Auth(Session $session, array $config = []) +new Auth(Session $session, ?Cookies $cookies = null, array $config = []) login(array $userData, bool $remember = false): void logout(): void check(): bool