Installation
Run composer require dorcyv/jwt-session-bundle in your Laravel project root.
(Note: While the package is Symfony-focused, Laravel can leverage its core logic via a custom session driver or middleware.)
Configuration
Override Laravel’s default session driver in config/session.php:
'driver' => 'jwt', // Custom driver (see Implementation Patterns)
(The bundle itself doesn’t natively integrate with Laravel, so you’ll need to adapt it—see next section.)
First Use Case Test a JWT-based session by:
session(['jwt_test' => 'value']).X-JWT-Session cookie (or equivalent) in browser dev tools.Create a Custom Session Driver
Extend Laravel’s SessionManager to use the bundle’s JwtSessionHandler:
// app/Providers/AppServiceProvider.php
use Dorcyv\JwtSessionBundle\Session\JwtSessionHandler;
public function register()
{
$this->app->extend('session', function ($app) {
$handler = new JwtSessionHandler(
$app['config']['jwt_session.key'],
$app['config']['jwt_session.ttl']
);
return new \Illuminate\Session\Store(
$handler,
new \Illuminate\Session\Middleware\StartSession()
);
});
}
Configure JWT Settings
Add to config/session.php:
'jwt_session' => [
'key' => env('JWT_SECRET', 'your-256-bit-secret'),
'ttl' => 3600, // Token lifetime (seconds)
'algorithm' => 'HS256', // Default algorithm
],
Middleware for JWT Validation Protect routes with a middleware to validate the JWT cookie:
// app/Http/Middleware/ValidateJwtSession.php
public function handle($request, Closure $next)
{
$jwt = $request->cookie('X-JWT-Session');
if (!$jwt || !JwtSessionHandler::validate($jwt)) {
abort(403, 'Invalid session');
}
return $next($request);
}
Fallback for Legacy Sessions
Use a hybrid approach with a session() helper that falls back to file storage if JWT fails:
if (!session()->has('jwt_fallback')) {
session(['jwt_fallback' => true]);
}
/refresh-jwt).Cookie Size Limits
compact serialization.CSRF Vulnerabilities
SameSite attributes.SameSite=Strict and use Laravel’s csrf_token() middleware.Token Revocation
Algorithm Mismatches
algorithm in config/session.php matches the key length (e.g., HS256 requires a 32-byte/256-bit key).openssl random -base64 32 to generate a secure key.Laravel Cache Integration
cache()->remember() for non-JWT data.use Firebase\JWT\JWT;
$decoded = JWT::decode($jwt, env('JWT_SECRET'), ['HS256']);
dd($request->headers()) to inspect the X-JWT-Session cookie.public function handle($request, Closure $next)
{
\Log::debug('JWT Session Payload:', [
'token' => $request->cookie('X-JWT-Session'),
'data' => session()->all()
]);
return $next($request);
}
Custom Claims
Extend the JwtSessionHandler to add custom claims (e.g., user roles):
$handler = new JwtSessionHandler($key, $ttl, [
'iss' => 'your-app',
'roles' => ['admin'] // Custom claim
]);
Encrypted Payloads Encrypt sensitive session data before storing in the JWT:
use Dorcyv\JwtSessionBundle\Session\Encryptor;
$encryptedData = Encryptor::encrypt(session('sensitive_data'));
session(['encrypted_data' => $encryptedData]);
Multi-Server Sync
Use a shared Redis cache for token metadata (e.g., jwt:revoked:{token_hash}) to simulate revocation without full server-side sessions.
Fallback Driver
Create a JwtFallbackSessionHandler that switches to file or database if JWT validation fails:
class JwtFallbackSessionHandler implements SessionHandlerInterface
{
protected $jwtHandler;
protected $fallbackHandler;
public function __construct()
{
$this->jwtHandler = new JwtSessionHandler(...);
$this->fallbackHandler = new \Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler();
}
public function read($sid)
{
try {
return $this->jwtHandler->read($sid);
} catch (\Exception $e) {
return $this->fallbackHandler->read($sid);
}
}
// Implement other SessionHandlerInterface methods...
}
How can I help you explore Laravel packages today?