Skip to content

Cookies ​

Overview ​

Nexphant provides a secure cookie API with:

  • Signed cookies
  • Encrypted cookies
  • SameSite support
  • Secure and HttpOnly flags
  • Builder pattern

Basic Usage ​

php
$app->get('/set', function () {
    cookie()->make('theme', 'dark');
    
    return ['success' => true];
});
php
$app->get('/get', function (Request $request) {
    $theme = $request->cookie('theme', 'light');
    
    return ['theme' => $theme];
});
php
$app->get('/delete', function () {
    cookie()->forget('theme');
    
    return ['success' => true];
});

Fluent API ​

php
cookie()
    ->make('user_pref', 'value')
    ->maxAge(3600)           // 1 hour
    ->path('/')
    ->domain('.example.com')
    ->secure()               // HTTPS only
    ->httpOnly()             // No JS access
    ->sameSiteLax();         // CSRF protection

Method Chaining ​

php
$cookie = cookie()
    ->make('session_id', $sessionId)
    ->maxAge(60 * 60 * 24)   // 24 hours
    ->httpOnly()
    ->secure()
    ->sameSiteStrict();

Expiration ​

Max Age ​

php
// Expires in 1 hour
cookie()->make('temp', 'value')->maxAge(3600);

// Expires in 30 days
cookie()->make('remember', 'token')->maxAge(60 * 60 * 24 * 30);
php
// Deleted when browser closes
cookie()->make('session', 'value');
php
// Set expiration to past
cookie()->forget('name');

Security ​

Secure Flag ​

Only send over HTTPS:

php
cookie()
    ->make('token', $value)
    ->secure();

HttpOnly Flag ​

Prevent JavaScript access:

php
cookie()
    ->make('session', $value)
    ->httpOnly();

SameSite ​

Protect against CSRF:

php
// Strict - never sent cross-site
cookie()->make('csrf', $token)->sameSiteStrict();

// Lax - sent on top-level navigation
cookie()->make('session', $id)->sameSiteLax();

// None - sent cross-site (requires Secure)
cookie()->make('tracking', $id)->sameSiteNone()->secure();

Signed Cookies ​

Verify cookie integrity:

php
// Set signed cookie
cookie()
    ->make('user_id', '123')
    ->signed();

// Verify and get value
$userId = $request->signedCookie('user_id');

if ($userId === null) {
    // Cookie was tampered with
}

Encrypted Cookies ​

Encrypt sensitive data:

php
// Set encrypted cookie
cookie()
    ->make('api_token', $token)
    ->encrypted();

// Decrypt and get value
$token = $request->encryptedCookie('api_token');

Complete Examples ​

Remember Me ​

php
$app->post('/login', function (Request $request) {
    $credentials = $request->json();
    $remember = $credentials['remember'] ?? false;
    
    // Authenticate...
    
    session()->regenerate();
    session()->put('user_id', $user->id);
    
    if ($remember) {
        $token = bin2hex(random_bytes(32));
        
        User::query()
            ->where('id', $user->id)
            ->update(['remember_token' => hash('sha256', $token)]);
        
        cookie()
            ->make('remember_token', $token)
            ->maxAge(60 * 60 * 24 * 30) // 30 days
            ->httpOnly()
            ->secure()
            ->sameSiteLax();
    }
    
    return ['success' => true];
});

User Preferences ​

php
$app->post('/preferences', function (Request $request) {
    $prefs = $request->json();
    
    cookie()
        ->make('theme', $prefs['theme'])
        ->maxAge(60 * 60 * 24 * 365); // 1 year
    
    cookie()
        ->make('language', $prefs['language'])
        ->maxAge(60 * 60 * 24 * 365);
    
    return ['success' => true];
});

$app->get('/preferences', function (Request $request) {
    return [
        'theme' => $request->cookie('theme', 'light'),
        'language' => $request->cookie('language', 'en'),
    ];
});

Analytics Tracking ​

php
$app->get('/track', function (Request $request) {
    $visitorId = $request->cookie('visitor_id');
    
    if (!$visitorId) {
        $visitorId = bin2hex(random_bytes(16));
        
        cookie()
            ->make('visitor_id', $visitorId)
            ->maxAge(60 * 60 * 24 * 365 * 2) // 2 years
            ->httpOnly()
            ->sameSiteLax();
    }
    
    // Log visit...
    
    return ['visitor_id' => $visitorId];
});

CSRF Token ​

php
$app->get('/form', function () {
    $token = csrf()->token();
    
    cookie()
        ->make('XSRF-TOKEN', $token)
        ->httpOnly(false) // JS needs access
        ->sameSiteStrict();
    
    return ['csrf_token' => $token];
});

Configuration ​

config/cookie.php:

php
return [
    'path' => '/',
    
    'domain' => env('COOKIE_DOMAIN'),
    
    'secure' => env('COOKIE_SECURE', false),
    
    'http_only' => true,
    
    'same_site' => 'lax', // strict, lax, none
    
    'encrypt' => false,
    
    'sign' => true,
];

Multiple Cookies ​

php
$app->get('/setup', function () {
    cookie()->make('theme', 'dark')->maxAge(86400);
    cookie()->make('language', 'en')->maxAge(86400);
    cookie()->make('timezone', 'UTC')->maxAge(86400);
    
    return ['success' => true];
});

Cookies are queued and sent with response:

php
$app->get('/test', function () {
    // Queue cookies
    cookie()->make('a', '1');
    cookie()->make('b', '2');
    cookie()->make('c', '3');
    
    // All sent with response
    return ['success' => true];
});

Best Practices ​

  1. Always use Secure flag in production (HTTPS)
  2. Use HttpOnly for session/auth cookies
  3. Use SameSite=Lax or Strict for CSRF protection
  4. Encrypt sensitive data in cookies
  5. Set appropriate expiration times
  6. Minimize cookie size (4KB limit)
  7. Use signed cookies to prevent tampering
  8. Validate cookie values server-side
  9. Clear cookies on logout
  10. Use SameSite=None only when necessary

Security Checklist ​

  • [ ] Secure flag enabled in production
  • [ ] HttpOnly for authentication cookies
  • [ ] SameSite set appropriately
  • [ ] Sensitive data encrypted
  • [ ] Cookies signed or encrypted
  • [ ] Reasonable expiration times
  • [ ] Cookie values validated
  • [ ] Clear cookies on logout
  • [ ] Domain restriction configured
  • [ ] Path restriction configured

Next Steps ​

Released under the MIT License.