In my PHP Laravel application, each user (User model) belongs to an organization (Organization model). I need to be able to configure the session lifetime (session.lifetime config value) separately for each user based on the organization.
The value is stored in the database -> organizations table -> session_lifetime column (integer). Organization's admin users are able to change it in the admin page.
I have created a CustomSessionLifetime middleware:
public function handle(Request $request, Closure $next)
{
$user = auth()->user();
if ($user !== null)
{
$lifetime = $user->organization->session_lifetime;
config()->set('session.lifetime', $lifetime);
}
return $next($request);
}
Now I have kind of a circular problem:
1) If I set the CustomSessionLifetime middleware to run BEFORE StartSession middleware, like this:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
//...
\App\Http\Middleware\CustomSessionLifetime::class,
\Illuminate\Session\Middleware\StartSession::class,
//...
],
then I am unable to get the user (and thus the organization or the session_lifetime attribute value) using auth()->user() function because the session is not yet started.
2) If I set the CustomSessionLifetime middleware to run AFTER StartSession middleware, like this:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
//...
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\CustomSessionLifetime::class,
//...
],
then I am unable to configure the session.lifetime config value because the session is already started and the old value has been used there.
I was kind of surprised that Laravel didn't have a native way to achieve something like this as I think it seems pretty standard to want to customize the session lifetime based on user somehow.
How could I make this work?
I think I found a pretty decent workaround for this, by using two custom middlewares and a cookie.
BeforeStartSession.phpmiddleware:AfterStartSession.phpmiddleware:These are added to the
$middlewareGroupsarray in theKernel.phpfile so they are before and after theStartSessiondefault middleware:I also added the cookie manually in my login controller after succesfully logging the user in so the
BeforeStartSessionmiddleware picks up the correct value immediately after redirecting the user:The only downside in this is that as cookies are stored client side, users are able to remove them (even if they are re-added after every request), decreasing the security of it. I countered this by having the default lifetime pretty low value.
This of course also adds some extra data to all requests as the Laravel cookie values are encrypted.