Force logout of specific user by user id in Laravel
Solution 1
Currently, there's no straightforward way to do this; As the StatefulGuard
contract and its SessionGuard
implementation don't offer a logoutUsingId()
as they do for login.
You need to add a new field to your users table and set it to true when you want a specific user to be logged out. Then use a middleware to check if the current user needs a force logout.
Here's a quick implementation.
1. Add a new field
Let's add a new field to users table migration class:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
// ...
$table->boolean('logout')->default(false);
// other fields...
});
}
// ...
}
Make sure you run php artisan migrate:refresh [--seed]
after changing the migration.
2. Force logout middleware
Let's create a new middleware:
php artisan make:middleware LogoutUsers
Here's the logic to check if a user needs to be kicked out:
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
class LogoutUsers
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = Auth::user();
// You might want to create a method on your model to
// prevent direct access to the `logout` property. Something
// like `markedForLogout()` maybe.
if (! empty($user->logout)) {
// Not for the next time!
// Maybe a `unmarkForLogout()` method is appropriate here.
$user->logout = false;
$user->save();
// Log her out
Auth::logout();
return redirect()->route('login');
}
return $next($request);
}
}
3. Register the middleware in HTTP kernel
Open up the app/Http/Kernel.php
and add your middleware's FQN:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\LogoutUsers::class, // <= Here
],
'api' => [
'throttle:60,1',
'bindings',
],
];
It's untested code, but it should give you the idea. It'd be a good practice to add a couple of API methods to your User
model to accompany with this functionality:
-
markedForLogout()
: Checks user'slogout
flag. -
markForLogout()
: Sets user'slogout
flag totrue
. -
unmarkForLogout()
: Sets user'slogout
flag tofalse
.
Then on the administration side (I suppose it's your case), you just need to call markForLogout()
on the specific user model to kick him out on the next request. Or you can utilize the query builder to set the flag, if the model object is not available:
User::where('id', $userId)
->update(['logout' => true]);
It can be a markForLogoutById($id)
method.
Related discussions
[Proposal] Log out users by ID
Multiple statements when logged users are deleted
Solution 2
Use the setUser to find a soluion
-
get current user
$user = Auth::user();
-
logout user you want to, by id
$userToLogout = User::find(5); Auth::setUser($userToLogout); Auth::logout();
-
set again current user
Auth::setUser($user);
Solution 3
I suggest you to override App\Http\Middleware\Authenticate handle function with custom check
if ($this->auth->user()->deleted_at) {
$this->auth->logout();
return redirect()->route('login');
}
Solution 4
The setup and below code I use it to logout a user and also lock his account(optional)using checklist, I did it through Ajax Request:
-In config/session.php, change to:
'driver' => env('SESSION_DRIVER', 'database'),
-run php artisan session:table -run php artisan migrate //a session table is created.
-in .env file: change SESSION_DRIVER=file to SESSION_DRIVER=database
Now the coding part: -In controller:
function ajaxCheckList(Request $request)
{
// \Log::info($request);
$user = \App\Models\User::findOrFail($request['user_id']);
$locked = 0;
if ($user->locked == 1) {
$user->locked = 0;
$locked = 0;
} else {
$user->locked = 1;
$locked = 1;
DB::table('sessions')
->where('user_id', $request['user_id'])
->delete();
}
$user->update(['locked' => $locked]);
}
Dani Banai
I have a high motivation and endless hunger to learn, optimize and contribute for better environment and strong passion for developing exciting products that will be used by millions of people worldwide in order to change the world for the best. My expertise: Developing flexible & unbreakable code My point of view: "No pain. No Gain!".
Updated on July 15, 2022Comments
-
Dani Banai almost 2 years
I use Laravel 5.2, and I want to know how to force a user to log out by id. I'm building an admin panel with the option to deactivate a specific user that is currently logged in to the web application. Laravel gives you this option for a current user.
Auth::logout()
But I don't want to log out the current user, as I am an authenticated user. So I need to force log out of a specific user by its
id
. Just like when we log in a user with a specific id.Auth::loginUsingId($id);
Is there something like the following?
Auth::logoutUsingId($id);
-
Kashif Saleem almost 5 yearsyou can simply Auth::logout(); for logout
-
Imad Ullah almost 5 yearsDear @KashifSaleem! Simply Auth::logout(); will log out the current user, here our concern is to logout a user other then the current user.