I have implemented socialite login using Google and LinkedIn. My requirements are that I need to have the user only be able to login from one device at a time, so in case the user logs in using another device the first logged in device will be logged out.
I have two types of users, ones that login using a normal sign up process and the ones that use Socialite login. If a user has used the same email on a normal sign up and he wants to login using google or linked-in his account will be the same.
I have two tables one for admins and one for users as well, and two different models.
If my user signs in using his username and password I managed to make it work using the following code:
In session.php
'expire_on_close' => true,
In CustomDatabaseSessionHandler.php
<?php
namespace AppExtensions;
use IlluminateContractsAuthGuard;
use IlluminateContractsContainerBindingResolutionException;
use IlluminateSessionDatabaseSessionHandler;
class CustomDatabaseSessionHandler extends DatabaseSessionHandler
{
/**
* Add the user information to the session payload.
*
* @param array $payload
* @return $this
* @throws BindingResolutionException
*/
protected function addUserInformation(&$payload): static
{
if ($this->container->bound(Guard::class)) {
info(($this->user() ? get_class($this->user()) : null));
$payload['userable_type'] = $this->user() ? get_class($this->user()) : null;
$payload['userable_id'] = $this->userId();
}
return $this;
}
/**
* Get the currently authenticated user's ID.
*
* @return mixed
* @throws BindingResolutionException
*/
protected function user(): mixed
{
return $this->container->make(Guard::class)->user();
}
}
In AppServiceProvider
Session::extend('custom-database', function ($app) {
$table = $app['config']['session.table'];
$lifetime = $app['config']['session.lifetime'];
$connection = $app['db']->connection($app['config']['session.connection']);
return new CustomDatabaseSessionHandler($connection, $table, $lifetime, $app);
});
Changed the SESSION_DRIVER in .env to ‘custom-database’
Created a LoginListener with the following code:
<?php
namespace AppListeners;
use IlluminateSupportFacadesDB;
class LoginListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(object $event): void
{
$user = $event->user;
DB::table('sessions')->where('userable_id', $user->id)->where('userable_type', get_class($user))->delete();
}
}
I have added the following to services.php
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('APP_URL') . '/oauth/google/callback',
],
'linkedin-openid' => [
'client_id' => env('LINKEDIN_CLIENT_ID'),
'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
'redirect' => env('APP_URL') . '/oauth/linkedin_openid/callback',
],
My problem is whenever i close the browser it’s not logging out, and whenever i am logging in using another device it’s not logging out, this problem is happening only when using the socialite login.