phplaravellaravel-fortify

Laravel logoutOtherDevices with Fortify


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.


Solution

  • 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.