Session not working in middleware Laravel 5

2020-02-13 08:24发布

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.

6条回答
别忘想泡老子
2楼-- · 2020-02-13 08:33

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',
    ],
];
查看更多
倾城 Initia
3楼-- · 2020-02-13 08:37

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

查看更多
Juvenile、少年°
4楼-- · 2020-02-13 08:38

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;
        });
    }
}
查看更多
该账号已被封号
5楼-- · 2020-02-13 08:39

Another thing to note, if you're making some middleware that's manipulating/retrieving data from the session, you need to make sure it's loaded after StartSession web middleware.

查看更多
爷的心禁止访问
6楼-- · 2020-02-13 08:51

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.

查看更多
一夜七次
7楼-- · 2020-02-13 08:55

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.

查看更多
登录 后发表回答