How to store user ID in the Laravel session table
Storing the session ID in the database for your Laravel application can be very useful to allow user to manage their own sessions on other devices.
Alex Bouma
Founder Chief Tools
Sometimes you want to store the user id with the session so you can purge all sessions or even a single session creating a more secure system for your users, or maybe you want to see how many times a user is logged in. There are many use cases but it's not possible by default... so let's implement this nifty feature :)
Note
There is no need for custom cody anymore starting from Laravel 5.2 since this now comes out of the box.
Note: this guide only applies for the database
session driver, other drivers do not support this.
Let's modify the migration first:
1<?php 2 3use Illuminate\Database\Schema\Blueprint; 4use Illuminate\Database\Migrations\Migration; 5 6class CreateSessionTable extends Migration 7{ 8 /** 9 * Run the migrations.10 *11 * @return void12 */13 public function up()14 {15 Schema::create(config('session.table'), function (Blueprint $table) {16 $table->string('id')->unique();17 18 $table->integer('user_id')->unsigned()->nullable()->default(null);19 // You can even add a foreign key constraint if you want :)20 //$table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');21 $table->text('payload');22 23 $table->integer('last_activity');24 });25 }26 27 /**28 * Reverse the migrations.29 *30 * @return void31 */32 public function down()33 {34 Schema::dropIfExists(config('session.table'));35 }36}
We add a unsigned integer field representing our user to the default fields, we allow null since users that are not logged in have no user id. Run php artisan migrate
to run the migration.
Next we need to add our custom driver since we need to override a method on the database session driver provided by Laravel.
1<?php 2 3namespace App\Session; 4 5class DatabaseSessionHandler extends \Illuminate\Session\DatabaseSessionHandler 6{ 7 /** 8 * {@inheritDoc} 9 */10 public function write($sessionId, $data)11 {12 $user_id = (auth()->check()) ? auth()->user()->id : null;13 14 if ($this->exists) {15 $this->getQuery()->where('id', $sessionId)->update([16 'payload' => base64_encode($data), 'last_activity' => time(), 'user_id' => $user_id,17 ]);18 } else {19 $this->getQuery()->insert([20 'id' => $sessionId, 'payload' => base64_encode($data), 'last_activity' => time(), 'user_id' => $user_id,21 ]);22 }23 24 $this->exists = true;25 }26}
We also need a service provider to register our new driver with Laravel, I used a different driver name (app.database
) but you could also override the default database driver (called database
) if you want.
1<?php 2 3namespace App\Providers; 4 5use Illuminate\Support\ServiceProvider; 6use App\Session\DatabaseSessionHandler; 7 8class SessionServiceProvider extends ServiceProvider 9{10 /**11 * Register the service provider.12 *13 * @return void14 */15 public function register()16 {17 $this->app->session->extend('app.database', function ($app) {18 $lifetime = $this->app->config->get('session.lifetime');19 $table = $this->app->config->get('session.table');20 $connection = $app->app->db->connection($this->app->config->get('session.connection'));21 22 return new DatabaseSessionHandler($connection, $table, $lifetime, $this->app);23 });24 }25}
Add the service provider to the providers array in your config/app.php
and change the driver name to app.database
in your config/session.php
config file.
If you now browse around your app and log in and out you will see the session table add and remove the user id accordingly.
Now you could add a Eloquent model for the sessions table and add the relation to your users model and query away on the sessions :)