I built a Laravel app with Fortify authentication. There was a requirement that when the users log in, they should be logged out from all other devices. In the Laravel documentation, it is mentioned that I can use the Auth::logoutOtherDevices($password);
method. But it is not clear how to use this with Fortify.
I tried to use this inside the Fortify::authenticateUsing(function (Request $request) {})
function, but it doesn't work as it checks for a User
instance inside the logoutOtherDevices()
method in the Illuminate\Auth\SessionGuard
class.
By digging a little more in the Laravel\Fortify\Http\Controllers\AuthenticatedSessionController
class, I found out that I can pass in a custom login pipeline array in the app/config/fortify.php
and add my own handler to call the logoutOtherDevices()
method from there.
I managed to get it working in this way. But I feel something is off with this approach, and I want to see if there's an obvious way to do this (Am I missing something here ?)
Thanks.
Adding my current solution with the hope that it will help someone.
If you look at the fortify authentication related classes, you will see that the authentication flows through a pipeline of several handler classes. Although it is not documented, you can customize this flow and add an extra handler by overriding the following in the config/fortify.php
config file.
'pipelines' => [
'login' => [
Laravel\Fortify\Actions\AttemptToAuthenticate::class,
Laravel\Fortify\Actions\PrepareAuthenticatedSession::class,
App\Actions\Fortify\LogoutOtherDevices::class
]
]
If this block doesn't exist in the config file, you need to add this. The first two are required to get the default authentication process working. The last one: App\Actions\Fortify\LogoutOtherDevices::class
is my custom handler and that's where you'd add the code to logout the user from other devices.
Create the App\Actions\Fortify\LogoutOtherDevices
class as shown below and it will work.
<?php
namespace App\Actions\Fortify;
use Illuminate\Support\Facades\Auth;
class LogoutOtherDevices
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
// logout other devices
Auth::logoutOtherDevices($request->password);
return $next($request);
}
}
This works fine. But this is not documented anywhere, so there's a chance that they would change this behavior anytime. That's the reason I asked this question to see if there's any other way to do this.