Disallow Multiple Logins Of Same User in Laravel

In this article, I’m going to show how to prevent multiple logins of the same credentials in Laravel. I’m testing on Laravel 7. This method should work in most versions of Laravel. We’ll use Firebase to keep user sessions.

Table of Contents

  1. Create Firebase Project
  2. Modify Users Table
  3. Modify Login Controller
  4. Modify App Layout

Create Firebase Project

At first, create a Firebase project and get the Firebase credentials for the web. I’ve described how to create Firebase project & get credentials in this article. You may take a look.

Modify Users Table

To keep user session, we need a field in the users table. Go to data > migrations and in the users migration table add a field named session_id.

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->string('session_id')->nullable(); // our field
        $table->rememberToken();
        $table->timestamps();
    });
}

Now migrate the migration:

php artisan migrate

Modify Login Controller

Go to app/Http/Controllers/Auth and open LoginController.php. We are going to add two functions in this file named login & logout. Here’s the code:

LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use App\User;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */
    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function login(Request $request)
    {
        $this->validate($request, [
            'email' => 'required',
            'password' => 'required',
        ]);

        $user = User::where('email', $request->input('email'))->first();

        if (auth()->guard('web')->attempt(['email' => $request->input('email'), 'password' => $request->input('password')])) {

            $new_session_id = \Session::getId(); //get new session_id after user sign in

            if ($user->session_id != '') {
                $last_session = \Session::getHandler()->read($user->session_id);

                if ($last_session) {
                    if (\Session::getHandler()->destroy($user->session_id)) {

                    }
                }
            }

            User::where('id', $user->id)->update(['session_id' => $new_session_id]);

            $user = auth()->guard('web')->user();

            return redirect($this->redirectTo);
        }
        \Session::put('login_error', 'Your email and password wrong!!');
        return back();

    }

    public function logout(Request $request)
    {
        \Session::flush();
        \Session::put('success', 'Logout Successful!');
        return redirect()->to('/login');
    }
}

Modify App Layout

Navigate to resources > views > layouts and open app.blade.php file. Then copy the code from below and paste before </body> tag.

app.blade.php
<script src="https://www.gstatic.com/firebasejs/7.10.0/firebase-app.js"></script>
<script type="text/javascript">
    var session_id = "{!! (Session::getId())?Session::getId():'' !!}";
    var user_id = "{!! (Auth::user())?Auth::user()->id:'' !!}";

    // Your web app's Firebase configuration
    var firebaseConfig = {
        apiKey: "FIREBASE_API_KEY",
        authDomain: "FIREBASE_AUTH_DOMAIN",
        databaseURL: "FIREBASE_DATABASE_URL",
        storageBucket: "FIREBASE_STORAGE_BUCKET",
    };
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);

    var database = firebase.database();

    if ({!! Auth::user() !!}) {
        firebase.database().ref('/users/' + user_id + '/session_id').set(session_id);
    }

    firebase.database().ref('/users/' + user_id).on('value', function (snapshot2) {
        var v = snapshot2.val();

        if (v.session_id !== session_id) {

            console.log("Your account login from another device!!");

            setTimeout(function () {
                window.location = '/login';
            }, 4000);
        }
    });
</script>

Now run the project and test. That’s all.