Prevent Sessions For Routes in Laravel (Custom on-demand session handling)

10,855

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.

Share:
10,855
ʞɹᴉʞ ǝʌɐp
Author by

ʞɹᴉʞ ǝʌɐp

Renaissance Men of The 21st Century.

Updated on June 19, 2022

Comments

  • ʞɹᴉʞ ǝʌɐp
    ʞɹᴉʞ ǝʌɐ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
    Marco Florian over 8 years
    Add \Config::set('cookie.driver', 'array'); to also prevent the app from sending cookies in the response.
  • code-8
    code-8 over 6 years
    What do you mean app.conf ??
  • LukePOLO
    LukePOLO over 6 years
    should be config/app.php
  • LukePOLO
    LukePOLO over 6 years
    This will fail if you cache your config, not an idea situation
  • Stephen Lake
    Stephen Lake about 6 years
    Why 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
    newms87 almost 3 years
    This 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
    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 in Kernel.php