How to keep single session per user in Laravel

Standard

By now, most of you know about the PHP framework Laravel. It’s beautiful and those who haven’t tried this yet, please feel free to try it. I’m sure that you will love it. Coming to the requirement, our project required single session per user, meaning a user’s login process would clear all other sessions (or last session to be precise) from other devices or browsers for the same user. After a few study, here’s what I did to resolve it.

Added the following method in LoginController.php

/**
 * Swap a user session with a current one
 * 
 * @param \App\User $user
 * @return boolean
 */
protected function swapUserSession($user)
    {
        if (!($user instanceof \App\User)) {
            return false;
        }

        $new_session_id = Session::getId(); //get new session_id after user sign in
        $last_session = Session::getHandler()->read($user->last_session_id); // retrive last session

        if ($last_session) {
            Session::getHandler()->destroy($user->last_session_id);
        }

        $user->last_session_id = $new_session_id;
        $user->save();

        return true;
    }

Added a column ‘last_session_id’ in users table and in user model, added ‘last_session_id’ in the ‘fillable’ array.

That’s all. If you know any better method to handle this, please feel free to leave a comment.

Thanks for reading this post.

How to solve PHP warning: mkdir(): No such file or directory

Standard

I was on a Linux server and working on a Laravel project. All were working fine. Suddenly, we found that all mail related functionalities were crashing. From the log, we saw the SwiftMailer was trying to create cache in default /tmp folder and crashes with a warning saying:

warning: mkdir(): No such file or directory

I tried to run a simple PHP script that would create a folder or file under /tmp folder. It also produced the same warning.

PHP Code:

<?php
mkdir('/tmp/test');

To solve the issue, I’ve changed the TMPDIR environment variable in the boot() method of app/Providers/AppServiveProvider.php.

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        /**
         * Somehow PHP is not able to write in default /tmp directory and SwiftMailer was failing.
         * To overcome this situation, we set the TMPDIR environment variable to a new value.
         */
        if (class_exists('Swift_Preferences')) {
            \Swift_Preferences::getInstance()->setTempDir(storage_path().'/tmp');
        } else {
            \Log::warning('Class Swift_Preferences does not exists');
        }
    }

Please make sure that the new “tmp” folder location is writable by the web server.

This is the quickest solution that we had. For any other PHP frameworks, you can set a new TMPDIR location to solve this issue. If anyone knows the exact issue that causes the warning, please feel free to leave a comment.

Thank you for reading the post.