Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

BobZamin's avatar

How to add extra column to Session table and how to store data in it?

Hi. I'm trying to add an extra field to the sessions table so that along with the existing fields like user_id, user_agent, ip_address etc., the extra office_id column gets records stored in it on login.

I have: Changed the session driver both in config/sessions and .env files

config/session.php

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

Added office_id to the sessions migration file

Schema::create('sessions', function (Blueprint $table) {
            $table->string('id')->primary();
            $table->foreignId('user_id')->nullable()->index();
            $table->foreignId('office_id')->nullable()->index();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->text('payload');
            $table->integer('last_activity')->index();
            $table->timestamps();
        });

Ran

php artisan migrate:fresh --seed 

Extended the DatabaseSessionHandler

<?php

namespace App\Session;

class DatabaseSessionHandler extends \Illuminate\Session\DatabaseSessionHandler
{
    /**
     * {@inheritDoc}
     */

    protected function officeId()
    {
        return $this->container->make('request')->header('office');
    }

    public function write($sessionId, $data)
    {
        $user_id = (auth()->check()) ? auth()->user()->id : null;
        $office_id = $this->officeId();

        if ($this->exists) {
            $this->getQuery()->where('id', $sessionId)->update([
                'payload' => base64_encode($data), 'last_activity' => time(), 'user_id' => $user_id, 'office_id' => $office_id,
            ]);
        } else {
            $this->getQuery()->insert([
                'id' => $sessionId, 'payload' => base64_encode($data), 'last_activity' => time(), 'user_id' => $user_id, 'office_id' => $office_id,
            ]);
        }

        $this->exists = true;
    }
}

Wrote a SessionServiceProvider and registered it in config/app.php in Provider array

App/Providers/SessionServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Session\DatabaseSessionHandler;

class SessionServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->session->extend('app.database', function ($app) {
            $lifetime   = $this->app->config->get('session.lifetime');
            $table      = $this->app->config->get('session.table');
            $connection = $app->app->db->connection($this->app->config->get('session.connection'));

            return new DatabaseSessionHandler($connection, $table, $lifetime, $this->app);
        });
    }
}

config/app.php

App\Providers\SessionServiceProvider::class,

Wrote the logic to get the Office name at login (the user picks the office from dropdown on login screen)

 protected function attemptLogin(Request $request)
    {
        $office = Office::where('name', $request->office)->first();
        if($office && $office->is_active === 1) {
            return $this->guard()->attempt(
                ['username' => $request->username, 'password' => $request->password, 'is_active' => 1], $request->filled('remember')
            );
        }
    }

But when the user logs in, the database gets filled with records for all other fields except the office_id. What is missing? Am I doing it wrong? Is there an easier way of doing this? Do I have to create a model for the Session to be able to store the office_id to the sessions table? How do I get the user request information to the DatabaseSessionHandler to extract office name from it?

Please help figure this out. Thank you in advance.

0 likes
10 replies
martinbean's avatar

@bobzamin You’re using the session completely wrong. Just store whatever data you need in the session itself.

Snapey's avatar

personally i would save the office and the login time back to the user model

or just create a logins table and model

BobZamin's avatar

What I'm trying to do this for is I want to be able to show in an admin view which users are logged in to which office and if they are still logged in. The view should show for example: office1>user1 and user2 are logged in office2>user3 and user4 are logged in.

As soon as the user logs out or his session expires, the admin should see it disappear from the office. office1>user1 is logged in

The problem with storing office and user in the users table was: If I store the user and the office from which he was logged in into the users table, how to tell laravel to remove that record from the DB is case the user session expires.

Snapey's avatar

look in the sessions table to see who has active sessions

for each active user look in their user model for their office

BobZamin's avatar

@snapey I did as you said, looked in the sessions table for active session, took the user_id and looked up the office associated with that user_id. It works if user logs in and out, but if a users session expires, the session records on the sessions table remain the same and so the page shows the user still logged in in the office.

How do I remove the user from session table and also from the admin view if his session expires?

Can't do it with middleware either, as middleware only gets fired if the user send request. In case the user sends no more requests, the view will keep showing him as logged in.

Snapey's avatar

only records in the session table that are newer than the applications session duration are possibly on line

so records older than two hours (default) you can assume they have gone away

Kintheranger's avatar

I've got similar use case to Bob. Was there a resolution you came upon?

BobZamin's avatar

@Kintheranger that was a long time ago, I created a middleware to check the user activity with a timer equal to the session lifetime. This middleware kicks the user out (logs him out and clears his session) if he was inactive (if the user didn't send any request). If the user jiggled (if the user sent a request) before the middleware time ran out, the time in the middleware was reset.

Snapey's avatar

@BobZamin Seems a complicated way of doing what the system already does. If the user comes back after their session expired then they are already logged out, and you can't tell if they were ever logged in. If they don't come back, your middleware presumably never runs.

BobZamin's avatar

@Snapey thank you for your reply and all your help. I had to find a way to show the admin which users are currently logged in and active at each office in his dashboard. The problem was when their session expired, the admin dashboard still showed them as logged in. I spent so many hours on solving this problem and finally the middleware timer thing worked. It updated the admins dashboard information on how many users are in each office instantly on login, logout and if their session expired.

Please or to participate in this conversation.