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
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:
<?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.
<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.
Md Obydullah
Software Engineer | Ethical Hacker & Cybersecurity...
Md Obydullah is a software engineer and full stack developer specialist at Laravel, Django, Vue.js, Node.js, Android, Linux Server, and Ethichal Hacking.