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

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 void
12 */
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 void
31 */
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 void
14 */
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 :)

Need help?

We are happy to help you with any questions you might have.

  Documentation   Roadmap   Report a bug   Get in touch