Laravel 5 - 会话不起作用

Posted

技术标签:

【中文标题】Laravel 5 - 会话不起作用【英文标题】:Laravel 5 - session doesn't work 【发布时间】:2015-06-03 11:59:57 【问题描述】:

这里是config/session.php

return [
    'driver' => 'file',
    'files' => storage_path().'/framework/sessions',
];

我的storage/framework/sessions 有 755 个权限。

当我将这两行放在我的控制器中时

Session::set('aa', 'bb');
dd(Session::get('aa'));

我收到预期的"bb" 输出。但如果我评论第一行:

// Session::set('aa', 'bb');
dd(Session::get('aa'));

刷新页面,我仍然期待"bb",但得到null

另外,storage/framework/sessions 是空的。

我应该怎么做才能使 Session 正常工作?

【问题讨论】:

storage/framework/sessions 的所有者是谁? 755 表示只有所有者可以写入目录。因此,要使这些权限正常工作,所有者最常见的应该是网络服务器用户,通常类似于www-dataapache 等,具体取决于您使用的 Linux 发行版和 HTTP 服务器。 尝试将其设置为775 @Bogdan 我认为这与权限无关,设置为 777 并且会话仍然无法正常工作。 只是累了 cookiedatabase 司机,同样的:/这很奇怪。 我认为这是因为 Laravel 有一个自定义的会话处理程序,并且在负责将会话数据实际存储在文件中的代码可以执行之前,执行 dd() 会中断请求生命周期。尝试使用var_dump() 而不是dd() 【参考方案1】:

Laravel 5 通过一个名为 StartSession 的中间件类来处理会话。更重要的是,这个中间件是TerminableMiddleware,实际保存数据的代码(在您的情况下保存到会话文件中)位于terminate 方法中,该方法在请求生命周期结束时运行:

public function terminate($request, $response)

    if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions())
    
        $this->manager->driver()->save();
    

调用dd(Session::get('aa'));时,请求在中间件的terminate方法被调用之前就被中断了。

有趣的是,Laravel Middleware Documentation 实际上以 Laravel StartSession 中间件为例解释了可终止中间件的逻辑:

例如,Laravel 中包含的“会话”中间件在响应发送到浏览器之后将会话数据写入存储。

话虽如此,请尝试使用var_dump() 而不是dd()

【讨论】:

@limonte 您的问题很有趣,因此我决定进行一些挖掘以了解确切原因。我已经更新了答案,对实际发生的事情进行了更详细的解释。 感谢您的解释。有没有办法在请求结束之前保存会话内容?我知道我们可以手动调用 Session::save() 但这似乎不起作用。我真的需要能够这样做! @thiout_p 您使用的是什么会话驱动程序?如果您使用除cookie 之外的任何驱动程序,则使用Session::save() 将起作用,因为会话会立即写入。但是,如果您使用的是 cookie 驱动程序,那么会话将无法持续,因为 cookie 存储在客户端上并与应用程序响应一起发送,并且由于 dd 而不再发送该响应。 感谢您的回答。我在 SESSION_DRIVER 记录的键的 .env 文件中有一个错字,缺少 R 我正在处理其他事情,所以我无法检查这是否相关。 (但我想它会!)无论如何,谢谢你的解释! :) 如果你使用 dump() 也会发生同样的情况。它搞砸了会议!【参考方案2】:

使用 laravel 5.*,您必须像下面这样更改内核文件:

  'api' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Session\Middleware\StartSession::class,
            'throttle:60,1',
            'bindings',
        ],

然后转到 storage/framework/session 文件夹并将权限更改为 755,如果它有其他数量,然后删除 storage/framework/session 路径中的所有文件,再次使用您的代码将某些内容放入会话中,观看存储/框架/会话文件夹。

如果你的会话工作,你现在可以看到属于会话的奇怪的长文件,你就完成了!

如果您的问题尚未解决,请转到配置/会话并更改:

'driver' => env('SESSION_DRIVER', 'file')

到另一个预定义的数量,例如:

'driver' => env('SESSION_DRIVER', 'array'),

甚至

'driver' => env('SESSION_DRIVER', 'database'),

最后,如果你有一个空的 storage/framework/session 文件夹,你肯定还是有问题!!!

【讨论】:

是的。在 laravel 6.* 中需要添加内核文件,'api' only \Illuminate\Session\Middleware\StartSession::class【参考方案3】:

如果您使用 api route ,您的会话可能会遇到此问题,并且大多数时间会话返回 null , 尝试为此使用网络路由

【讨论】:

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

Laravel 4.2中的会话不起作用

使用ajax调用的角度保存变量到laravel会话不起作用

Laravel Redis 会话驱动程序不起作用

在同一控制器中以其他方法访问会话数据在 laravel 中不起作用

为啥 Laravel 4 CSRF 令牌不起作用?

Laravel 5.5 文件扩展验证不起作用