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

Posted

技术标签:

【中文标题】会话在中间件 Laravel 5 中不起作用【英文标题】:Session not working in middleware Laravel 5 【发布时间】:2015-06-30 03:12:43 【问题描述】:

我正在尝试使用 Laravel 5 中间件中的会话,但它们不起作用。 具体来说 - var_dump(Session::all()); 在句柄方法的开头给了我一个值的数组 - _tokken,然后在这个方法的结尾

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

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

虽然我可能在 Session 中间件之前加载了我的中间件,这是真的,然后我切换了,现在我的 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',

    ];

所以我问 - 我做错了什么?

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

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

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

【问题讨论】:

我刚刚删除了我的答案,因为它不正确。我在项目的中间件中测试了Session::all(),它工作正常。抱歉回答不正确。 @limonte 不用担心,是的,我写了 Session::all() 返回 _token,但后来没有设置我自己的值 对我来说它按预期工作,即 _token、_previous 和我的自定义值 @limonte 也许您可以分享您的项目或其他什么?还是私下帮我? 你做到了吗? 【参考方案1】:

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

解决此问题的最佳方法,将您的语言中间件添加到 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',
    ],
];

【讨论】:

所以添加 StartSession 会破坏您的应用程序?这是哪个版本的 Laravel?因为它没有为我打破。 这行得通。为了我。我试图为会话变量中的所有视图设置一个变量。将中间件添加到 web 组是完全有意义的,我首先将它添加到全局中间件数组中。谢谢! @WoodyDRN 抱歉我的回复晚了。我很忙,我忘记了。此代码来自 Laravel 5.8。【参考方案2】:

如果您需要当前中间件中的会话,我发现了一个(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;
        );
    

【讨论】:

值得指出的是,这个例子实现了一个“后”中间件——它在应用处理请求之后运行。这可能不是大多数需要中间件会话的人想要的。要更改此设置,请删除 $response = $next($request); 行并将 return $response; 行更改为 return $next($request); 这肯定是丑陋的逻辑,因为这将执行代码,在某些情况下我们不需要执行代码。【参考方案3】:

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

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

1) php artisan make:middleware SetApplicationLanguage

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

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

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

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

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

但你可以这样做,只需使用 App::setLocale(Session::get('locale')) 代替,并且包含 Session 外观。

【讨论】:

当我将中间件添加到 $middlewareGroups 数组 'web' 时,在 Laravel 6 中为我工作 第 2 点帮助了我,即新的中间件出现在 StartSession 类之后。谢谢你:)【参考方案4】:

我遇到了同样的问题,如果某些条件为真,我在中间件中设置值并在同一位置取消设置。

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

你需要使用

\Session::save();

每当您想保存修改时,假设我想存储用户的语言

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

当您现在刷新时,您会发现新创建的密钥。

【讨论】:

这个 save 方法在 Laravel 5.2 中不是必需的 有时是必要的。如果你执行redirect()-&gt;route('myroute')-&gt;send(),它不会存储会话数据,所以你应该在前面加上Session::save(); 使用 v5.8 我还发现它在中间件调用的函数中是必要的。

以上是关于会话在中间件 Laravel 5 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Route::currentRouteAction 在 laravel 5.4 中不起作用

Laravel Sanctum Token API 身份验证在 Postman 中不起作用

护照身份验证在 laravel 5.3 中不起作用

barryvdh/laravel-cors 配置在 Laravel 5.6 中不起作用;忽略'allowedMethods'

注册在 Laravel 5 中不起作用

数据表在 Laravel 5.3 中不起作用