会话在中间件 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()->route('myroute')->send()
,它不会存储会话数据,所以你应该在前面加上Session::save();
。
使用 v5.8 我还发现它在中间件调用的函数中是必要的。以上是关于会话在中间件 Laravel 5 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Route::currentRouteAction 在 laravel 5.4 中不起作用
Laravel Sanctum Token API 身份验证在 Postman 中不起作用
barryvdh/laravel-cors 配置在 Laravel 5.6 中不起作用;忽略'allowedMethods'