Prevent Sessions For Routes in Laravel (Custom on-demand session handling)
Solution 1
Its really easy using the middleware in Laravel 5, I needed any request with an API key not to have a session and I simply did :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Session\Middleware\StartSession as BaseStartSession;
class StartSession extends BaseStartSession
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(\Request::has('api_key'))
{
\Config::set('session.driver', 'array');
}
return parent::handle($request, $next);
}
}
Also you will need to extend the SessionServiceProvider as follows:
<?php namespace App\Providers;
use Illuminate\Session\SessionServiceProvider as BaseSessionServiceProvider;
class SessionServiceProvider extends BaseSessionServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerSessionManager();
$this->registerSessionDriver();
$this->app->singleton('App\Http\Middleware\StartSession');
}
}
and place in your config/app.php
under providers
:
'App\Providers\SessionServiceProvider',
Also you must change it in your kernel file: App/Http/Kernel.php
, in the $middlewareGroups
section change the default entry, \Illuminate\Session\Middleware\StartSession::class,
to your new class \App\Http\Middleware\StartSession::class,
.
Solution 2
In Laravel 5, just don't use the StartSession
, ShareErrorsFromSession
, and VerifyCsrfToken
middlewares.
In my application I've moved these three middlewares from the web
group to a new stateful
group, and then I have included this stateful
group on routes which need to know about the session (in addition to web
in all cases, in my app at least). The other routes belong to either the web
or api
groups.
Now when making requests to the routes which are not using the stateful
middleware group session cookies are not sent back.
Solution 3
The simplest way to achieve this is to Make your own AppStartSession middleware that subclasses Illuminate\Session\Middleware\StartSession and the replace the class being used in kernel.php. The only method you need to override in your subclass is sessionConfigured() for which you can return false to disable the session or parent::sessionConfigured() to allow it.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Session\Middleware\StartSession;
class AppStartSession extends StartSession
{
protected function sessionConfigured(){
if(!\Request::has('api_key')){
return false;
}else{
return parent::sessionConfigured();
}
}
}
kernel.php (see *** comment for where the change is done)
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
// *** Replace start session class
// \Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\AppStartSession::class,
// *** Also comment these ones that depend on there always being a session.
//\Illuminate\View\Middleware\ShareErrorsFromSession::class,
//\App\Http\Middleware\VerifyCsrfToken::class,
];
/**
* The application's route middleware.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
];
}
Don't fight the framework, embrace it!
Solution 4
Since Laravel 5.2, when middleware groups were introduced, you may disable session for certain routes by defining them outside of the "web" middleware group (which includes the StartSession middleware responsible for session handling). As on latest 5.2.x versions the whole default routes.php file is wrapped with "web" middleware group, you need to make some modification in app/Providers/RouteServiceProvider.php
file, as described here.
Solution 5
Laravel default have two routes group called web
and api
, the api routes group default without session.
So, we can write any route role to routes/api.php
, will not use session default.
If not want to use the api prefix url, we can modify app\Providers\RouteServiceProvider
add a new group like this:
Route::middleware('api')
->namespace($this->namespace)
->group(base_path('routes/static.php'));
Now you can place any routes into routes/static.php
file will not to use session.
Hope helpful.
Comments
-
ʞɹᴉʞ ǝʌɐp almost 2 years
I am building APIs for my Android app using laravel and default session driver set to REDIS.
I found a good article here http://dor.ky/laravel-prevent-sessions-for-routes-via-a-filter/ which sort of serves the purpose.
However when ever I hit the url it also hits the redis and generates the key which is empty. Now I want avoid creating empty session keys in redis. Ideally it should not hit the redis How can I do that?
Can we customise sessios in a way so that sessions are generated only for specific routes (or disable for specific routes)?
I can explain more with specific use case, please let me know.
-
Marco Florian over 8 yearsAdd
\Config::set('cookie.driver', 'array');
to also prevent the app from sending cookies in the response. -
code-8 over 6 yearsWhat do you mean app.conf ??
-
LukePOLO over 6 yearsshould be config/app.php
-
LukePOLO over 6 yearsThis will fail if you cache your config, not an idea situation
-
Stephen Lake about 6 yearsWhy this hasn't gotten any attention is a little concerning in the sense that [these] Laravel "developers" aren't seeing the modular potential in the framework and instead choose to write hackish work arounds. The rest of these answers are complete bollocks.
-
newms87 almost 3 yearsThis is probably the best answer, just move routes that don't require the session into their own middleware group. I feel like this is the way Taylor would recommend.
-
Supun Kavinda over 2 years
Config::set
didn't work for me. However,return $next($request);
worked. I also had to change the session middleware inKernel.php