Laravel - destroy existing sessions on login

Is there a way to check if a user already has a valid session on another computer?

What I want to do is when a user logs in, wipes out other sessions they already have, so if they forget to log out of the computer, speak on campus or at work and then they log in at home, it will destroy those other 2 sessions so that they are no longer logged in?

Facebook uses this in some way.

My only thoughts so far is something with this:

$user = User::find(1); // find the user
Auth::login($user); // log them in 
Auth::logout(); // log them out hoping that it will destroy all their sessions on all machines
Auth::login($user); // log them in again so they have a valid session on this machine

      

I haven't had a chance to test this, and I don't know if it will Auth::login($user);

destroy all sessions for this user or just the current one.

Thank!

+3


source to share


4 answers


You can store the session_id in a custom model so that:

  • When the logout event (auth.logout) comes out, you clear it.

  • When a new registration event fires, you can check if the session_id attribute is null in the custom model.

  • If it doesn't: destroy the previous session:

Session :: getHandler () β†’ destroy ($ user-> session_id);



$ user-> session_id = Session :: getId ();

Hope it helps!

+4


source


Hope you see this work:

Session::regenerate(true);

      



a new session_id will be obtained.

+2


source


This may not be the best answer, but the first thing that came to my mind was a reduction in the session timeout.

In app-> config-> session.php there is a parameter for lifetime and expire_on_close (browser).

This time I'll try to take a look at it and see if anyone else comes up with something better.

0


source


I realize this is an old question, but there is now a method in laravel 5.6 that does exactly that, so it might be helpful if someone comes to this later. You can also very quickly apply this method to earlier versions of laravel.

See the docs at https://laravel.com/docs/5.6/authentication#invalidating-sessions-on-other-devices.

I had the same use case as you (log out in all other devices on login). I tried the default login method to add my own logic (by first copying the default login method from vendor /laravel/framework/src/illuminate/Foundation/Auth/AuthenticatesUsers.php)

This method has a line, if ($this->attemptLogin($request))

- inside this, before the return statement, add your call to logoutOtherDevices as shown below

if ($this->attemptLogin($request)) {

        //log out all other sessions
        Auth::logoutOtherDevices($request->password); //add this line

        return $this->sendLoginResponse($request);
}

      

Also make sure you comment the Illuminate\Session\Middleware\AuthenticateSession

software Illuminate\Session\Middleware\AuthenticateSession

in your app /Http/Kernel.php as per the docs

(note that I have not tested the above code as I was using an older version of laravel which does not have this method, see below). This should work in 5.6.

Older Laravel Versions

I was actually using laravel 5.5, so I didn't have access to this convenience method. Fortunately, it's easy to add. I opened larvel 5.6 project and copied the logoutOtherDevices method from vendor /laravel/framework/src/illuminate/Auth/SessionGuard.php - for reference which I pasted below

/**
 * Invalidate other sessions for the current user.
 *
 * The application must be using the AuthenticateSession middleware.
 *
 * @param  string  $password
 * @param  string  $attribute
 * @return null|bool
 */
public function logoutOtherDevices($password, $attribute = 'password')
{
    if (! $this->user()) {
        return;
    }

    return tap($this->user()->forceFill([
        $attribute => Hash::make($password),
    ]))->save();
}

      

Then I copied this to my LoginController - it could have gone somewhere of your choice, but I put it here for convenience / laziness. I had to change it a bit like $this->user()

below ( $this->user()

becomes Auth::user()

)

 /**
 * Invalidate other sessions for the current user.
 * Method from laravel 5.6 copied to here
 *
 * The application must be using the AuthenticateSession middleware.
 *
 * @param  string  $password
 * @param  string  $attribute
 * @return null|bool
 */
public function logoutOtherDevices($password, $attribute = 'password')
{
    if (! Auth::user()) {
        return;
    }

    return tap(Auth::user()->forceFill([
        $attribute => Hash::make($password),
    ]))->save();
}

      

Then I can call this method in my login method as stated earlier in my answer, with a slight adjustment - $this->logoutOtherDevices($request->password);

If you want to test this locally, it will work if you open your site to normal and incognito. When you log in, you will log out on a different one - although you need to refresh to see anything that has changed.

0


source







All Articles