会话在中间件 Laravel 5 中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29797952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:25:13  来源:igfitidea点击:

Session not working in middleware Laravel 5

phpsessionlaravellaravel-5

提问by Subject

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

我试图在 Laravel 5 中间件中使用会话,但它们不起作用。具体来说 -var_dump(Session::all());在 handle 方法开始时给我一个具有一个值的数组 - _tokken,然后在此方法结束时

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.

给我两个值的数组,_tokken 和我的 lang 键,但刷新后相同,据我所知,第二次刷新后应该有相同的结果。

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 -

我虽然也许我在会话中间件之前加载了我的中间件,这是真的,然后我切换了,现在我的 Kernel.php 看起来像这样 -

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 -

编辑:在 Illuminate\Session\Middleware\StartSession 中挖掘我发现了这个 -

//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.

作为评论,所以我对 session_status() 的测试并不相关。

回答by WoodyDRN

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.

我遇到了同样的问题,我在登录时使用 Sessions 存储语言环境,然后重定向到主仪表板,但是当中间件加载时,会话尚未启动。所以这是行不通的。

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

首先让我说,我不是 Laravel 专家,但这种方式适用于 Laravel 5.3:

1) php artisan make:middleware SetApplicationLanguage

1) php artisan make:middleware SetApplicationLanguage

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

2) 将此添加到 app/Http/Kernel.php $middlewareGroup 变量中:

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

Notice that this new Middleware comes AFTER the StartSession class.

请注意,这个新的中间件出现在 StartSession 类之后。

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

3)这是我的应用程序/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.

请注意,我没有在这个例子中使用 Session。那是因为当我在 StartSession 类之后添加我的中间件时,会话可以工作,但 Auth::user() 将再次可用,所以我可以只使用 Auth::user()->locale 而根本不需要 Sessions。

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

但是你可以这样做,只需使用 App::setLocale(Session::get('locale')) 代替,并且包括 Session 门面。

回答by Islam Al-Rayan

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.

当您现在刷新时,您将找到新创建的密钥。

回答by Haydar ?AH?N

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.

我有同样的问题。@WoodyDRN 说您需要将 StartSession 中间件添加到您的内核文件中,但这不是解决此问题的最佳方法。那么,我怎么知道呢?因为我添加并请求验证系统坏了。

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

解决此问题的最佳方法,将您的语言中间件添加到 Web 中间件数组

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',
    ],
];

回答by online Thomas

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

如果您需要当前中间件中的会话,我找到了一个(n)(丑陋的)解决方法。

<?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;
        });
    }
}

回答by Daniel Dewhurst

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 StartSessionweb middleware.

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

回答by midan888

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

我完全忘记了 404,一些文件得到 404(缺少图像)所以 nginx 将请求传递给 Laravel 应用程序以显示 404 页面,并且因为它是其他 url 我在那里取消设置。我认为在会话中存储语言内容是同样的问题。只需检查您的浏览器网络并查看加载页面时发出的请求,您可能同时设置和取消设置