简体   繁体   中英

Laravel Session make a request without updating sessions expiry

I'm displaying a front-end countdown of when the user's session will expire, I want to request the time left without updating it.

Here's what I have so far:

$ttl = Redis::ttl(config('cache.prefix') . ':' . Session::getId());
return response()->json($ttl);

Each time this is requested the ttl is reset back to the session.lifetime value.

The existing mapWebRoutes() method in app/Providers/RouteServiceProvider.php looks like this.

/**
 * Define the "web" routes for the application.
 *
 * These routes all receive session state, CSRF protection, etc.
 *
 * @param  \Illuminate\Routing\Router  $router
 * @return void
 */
protected function mapWebRoutes(Router $router)
{
    $router->group([
        'namespace' => $this->namespace, 'middleware' => 'web',
    ], function ($router) {
        require app_path('Http/routes.php');
    });
}

You can simply add something like the following to that method, or you could duplicate the code above which loads routes.php and remove the web middleware.

$router->get('session-ttl', function () {
  return response()->json(
    \Redis::ttl(config('cache.prefix') . ':' . cookie(config('session.cookie')));
  );
});

Or

$router->group([
    'namespace' => $this->namespace
], function ($router) {
    require app_path('Http/routes_wo_web.php');
});

I solved this by extending the StartSession middleware:

class StartSession extends \Illuminate\Session\Middleware\StartSession
{

    public function terminate($request, $response)
    {
        if (!$request->is('auth/ping')) {
            parent::terminate($request, $response);
        }
    }

}

Where auth/ping is the route I don't want the session to save on.

I then registered this in the app container as a singleton, so the terminate method resolves to the same instance:

In AppServiceProvider->register :

$this->app->singleton('App\Http\Middleware\StartSession');

The session stuff is handled by the Illuminate\\Session\\Middleware\\StartSession middleware, which is in the web middleware group.

The simplest solution would be to place your route outside the standard web middleware group.

If you need any of the other web middlewares, you can add them back to the route.

To actually use the session in your route, you have a couple of options:

  • you can make a Session middleware that does not terminate the session (extend the existing one, and override the handle method to just return $next($request) )
  • someone here's suggested that as it's a one off route, you could just start the session manually wherever you're handling your route (nick the code from the existing middleware - it's only a few lines).

I think the recommended solution would be to do it in a middleware, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM