清除Laravel中所有会话数据的Artisan命令

33
在 Laravel 中清除所有会话数据的 Artisan 命令是什么,我正在寻找这样的内容: ``` php artisan session:clear ```
$ php artisan session:clear

但显然它不存在。我该如何在命令行中清除它?

我尝试使用

$ php artisan tinker  
...
\Session::flush();

但它只刷新了一个用户的会话,我想要清除所有用户的所有会话。我该怎么做?

我尝试了以下代码:

artisan cache:clear

但是它并没有清除会话。


2
你可以手动从storage/framework/sessions中删除。你可以编写Artisan命令来自动化这个过程。 https://laravel.com/docs/5.6/artisan#writing-commands - Khurram Shahzad
我在暂存区有一个表格,在本地有一个文件,使用一个命令会更容易和更通用。 - Yevgeniy Afanasyev
我懒得运行Mysql Workbench来截断表。它加载太慢,需要太多步骤。 - Yevgeniy Afanasyev
11个回答

49

如果您正在使用基于文件的会话,则可以使用以下Linux命令清除会话文件夹:

rm -f storage/framework/sessions/*

2
请提供解释,我的意思是它不一定是一个“artisan command”,但只有在使用“文件驱动程序”作为您的“会话数据”时才能正常工作,对吗? - Yevgeniy Afanasyev
29
这也会删除.gitignore文件,该文件用于在提交时保留(空)文件夹。 - Clément Baconnier
1
@YevgeniyAfanasyev 根据您的反馈,答案已经进行了更新。 - benjaminhull
@ClémentBaconnier 它不会删除 .gitignore 文件。 - ekene

38

更新:这个问题似乎经常被问到,并且许多人仍在积极评论。

在实践中,使用

session_flush()

来清除会话是一个可怕的想法。

php artisan key:generate

这可能会造成各种问题。最好的方法是清除您正在使用的任何系统。


懒程序员清除所有会话的指南:

php artisan key:generate

由于指定了新的应用程序密钥,将使所有会话无效。

不那么懒惰的方法

php artisan make:command FlushSessions

然后插入

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use DB;

class flushSessions extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'session:flush';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Flush all user sessions';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        DB::table('sessions')->truncate();
    }
}

然后

php artisan session:flush

3
愉快地让用户注销吧 :D - user4796879
3
请注意,生成新的应用密钥将破坏您在 Laravel 中可能已加密的任何其他数据。 - Pablo
7
不要因为想摆脱会话而在生产应用程序中使应用程序密钥失效。这也会使所有加密(非哈希)数据变得不可读。也许你的应用程序并不存储任何加密数据,但在StackOverflow上向陌生人推荐这样做似乎不是一个好主意。 - miho
15
另外,答案的第二部分只适用于将会话存储到数据库中的情况。请注意,这通常不适用(例如,如果您使用Redis会话存储或使用cookie会话存储)。 - miho
1
Redis驱动程序怎么样?如何访问会话Redis连接? - Boris D. Teoharov
显示剩余9条评论

14
问题在于PHP的SessionHandlerInterface接口没有强制要求会话驱动程序提供任何形式的destroyAll()方法。因此,必须为每个驱动程序手动实现该方法。
从不同答案中汲取灵感,我想出了这个解决方案:
1.创建命令
php artisan make:command FlushSessions 
  1. app/Console/Commands/FlushSessions.php 中创建类。
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class FlushSessions extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'session:flush';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Flush all user sessions';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $driver = config('session.driver');
        $method_name = 'clean' . ucfirst($driver);
        if ( method_exists($this, $method_name) ) {
            try {
                $this->$method_name();
                $this->info('Session data cleaned.');
            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
        } else {
            $this->error("Sorry, I don't know how to clean the sessions of the driver '{$driver}'.");
        }
    }

    protected function cleanFile () {
        $directory = config('session.files');
        $ignoreFiles = ['.gitignore', '.', '..'];

        $files = scandir($directory);

        foreach ( $files as $file ) {
            if( !in_array($file,$ignoreFiles) ) {
                unlink($directory . '/' . $file);
            }
        }
    }

    protected function cleanDatabase () {
        $table = config('session.table');
        DB::table($table)->truncate();
    }
}
  1. 运行命令
php artisan session:flush

欢迎提供其他驱动程序的实现!

删除任何驱动程序的会话。使用此代码片段 \Session::getHandler()->gc(0) - adjustment layer
缺少"use Illuminate\Support\Facades\DB;"。Laravel 9.x及更高版本不需要构造函数。除此之外,这是一个不错的解决方案。 - undefined

14
如果你想完全删除任何驱动程序的会话。 请使用以下代码片段。
\Session::getHandler()->gc(0); // Destroy all sessions which exist more than 0 minutes

5

一个简单的方法来清除所有会话是更改会话cookie的名称。这可以通过更改config/session.php文件中的'cookie' => '...'行轻松完成。

这与您使用的会话存储无关,也不会触及任何其他数据,仅影响会话数据(因此对我来说似乎比更新应用程序密钥解决方案更可取,因为后者会丢失存储在应用程序中的任何加密数据)。


1
不错的解决方案,谢谢。你说得对。APP_KEY也是使用Hash::make()创建哈希时的盐。因此,在更改它后,用户密码和任何其他哈希数据都将无效。 - algorhythm
为什么在同一文件中更改“domain”不如这种方式好? - Yevgeniy Afanasyev
1
@algorhythm bcrypt密码将继续工作。对于其他密码哈希算法不确定。但是,您关于手动哈希的数据库列是正确的,这些列使用Laravel加密功能(因为这些需要解密,而不像密码)。 - Flame

1

我的解决方案
Laravel

// SESSION_DRIVER=file


$files = File::allFiles(storage_path('framework/sessions/'));
foreach($files as $file){
  File::delete(storage_path('framework/sessions/'.$file->getFilename()));
}
//OR

//SESSION_DRIVER=redis

Artisan::call('cache:clear'); // == php artisan cache:clear 


1

我知道这是一个老旧的线程,但对我有用的方法就是删除cookies。

在Chrome中,进入开发控制台,转到“应用程序”选项卡。在侧边栏中找到“Cookies”,并单击其前面的小箭头。进入您的域名,单击过滤字段旁边的图标以清除您域名的cookies。刷新页面,所有会话数据都是新的,旧的数据都被删除。


2
这对开发人员来说很棒,但用户呢? - Dazzle

1

这个帖子很旧了,但我想分享一下我的实现方式,可以移除基于文件的驱动程序中的所有会话。

        $directory = 'storage/framework/sessions';
        $ignoreFiles = ['.gitignore', '.', '..'];
        $files = scandir($directory);

        foreach ($files as $file) {
            if(!in_array($file,$ignoreFiles)) unlink($directory . '/' . $file);
        }

为什么我没有使用Linux命令“rm”?

因为Laravel需要PHP作为先决条件,而不是Linux。使用这个Linux命令将使我们的项目只能在Linux环境中实现。 这就是为什么在Laravel中使用PHP很好的原因。


0

如果您正在使用数据库作为会话驱动程序,则请清空会话表。如果您在许多子域上使用单个登录,则重新生成密钥将导致许多问题。清空会话表有助于减少会话表中的无用数据。您可以删除每个人浏览器上的cookie。


0

如果您使用数据库会话,请只需删除该表上的所有数据。在我的情况下,它是 'sessions' 表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接