简体   繁体   中英

Session not working in middleware Laravel 5

Im trying to work with Sessions in Laravel 5 Middleware, but they are not working. To be specific - var_dump(Session::all()); at the start of handle method gives me array with one value - _tokken, then at the end of this method

Session::put('lang',$locale);
var_dump(Session::all());

Gives me array with two values, _tokken and my lang key, but after refresh its the same, as I understand there should be same result after second refresh.

I though maybe I have my middleware loaded before Session middleware, which was true, then I switched and now my Kernel.php looks like this -

protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession',
        'App\Http\Middleware\VerifyCsrfToken',
        'App\Http\Middleware\Language',

    ];

So I ask - what am I doing wrong?

Edit: Digging in Illuminate\\Session\\Middleware\\StartSession I found this -

//Note that the Laravel sessions do not make use of PHP "native" sessions in any way since they are crappy.

as a comment, so my testing with session_status() is not relavent.

You need to use

\Session::save();

Whenever you want to save the modification so lets say I want to store the language of the user

\Session::put('lang','en');
\Session::save();

When you refresh now you will find your newly created key.

I had the same problem, I was using Sessions to store the locale at login, then redirect to the main dashboard, but when the middleware loads, the session is not initiated yet. So it wouldn't work.

Let me say first, I'm no Laravel expert, but this way works in Laravel 5.3:

1) php artisan make:middleware SetApplicationLanguage

2) Add this to app/Http/Kernel.php $middlewareGroup variable:

\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\SetApplicationLanguage::class,

Notice that this new Middleware comes AFTER the StartSession class.

3) This is my app/Http/MiddleWare/SetApplicationLanguage.php:

namespace App\Http\Middleware;

use App;
use Closure;
use Illuminate\Support\Facades\Auth;

class SetApplicationLanguage
{

    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request            
     * @param \Closure $next            
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (isset(Auth::user()->locale)) {
            App::setLocale(Auth::user()->locale);
        }

        return $next($request);
    }
}

Notice that I don't use Session in it this example. That's because when I add my Middleware AFTER the StartSession class, session would work, but Auth::user() would be available again, so I could just use Auth::user()->locale and no need for Sessions at all.

But you could do it, just use App::setLocale(Session::get('locale')) instead and of cause include the Session facade.

I had the same problem. @WoodyDRN said you need add StartSession middleware to your kernel file to you but it is not best way to solve this problem. So, how do I know that? Because I added and request the validation system is broken.

Best way to solve this problem, adding your language middleware to web middleware array

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\Localization::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

If you need the session in your current middleware I found a(n) (ugly) workaround.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Session\Middleware\StartSession;

class MiddlewareThatNeedsTheSession
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
     public function handle($request, Closure $next)
     {
        return app(StartSession::class)->handle($request, function ($request) use ($next) {

            /** @var Response $response */
            $response = $next($request);

            // do something with session
            session(['foo' => 'bar']);

            return $response;
        });
    }
}

另外需要注意的是,如果你正在制作一些操作/从会话中检索数据的中间件,你需要确保它在StartSession Web中间件之后加载。

I had same problem, I was setting value in Middleware and unsetting in same place if some condition is true.

I totally forgot about 404s, some files was getting 404 (missing images) so nginx was passing request to Laravel app to show 404 page, and because it was other url I was unsetting there. I think its the same issue with storing language stuff in session. Just check your browser networking and see what requests are being made while loading the page, you might be setting and unsetting at the same time

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