0

I am tracking the login history of a user in my website, and for that I need to display if there is any other session open in another browser or device. Plus, I need to provide a functionality wherein a user can logout a session that is open in a different browser/device from the current session. I am using redis-server. The things which I have done so far are as follows.

In the .env file, I have updated the CACHE_DRIVER and SESSION_DRIVER to redis.

In session.php and cache.php, I have set driver to redis.

Next, at the time of login, I connect to the redis server and store the session id for a specific user.

 $redis = Redis::connection();
 $redis->sadd('user:sessions:'. Auth::user()->id, $session_id); 

Once this is done, I can see the multiple session id's per user using redis-cli command.

> SMEMBERS user:sessions:1
> "95008658737a7f937c614bccbb748443a649c515"
> "f1f14db9b1760254a4072fe9b440f9acbacc8974"
> GET laravel:95008658737a7f937c614bccbb748443a649c515 
> "s:332:\"a:5:{s:6:\"_token\";s:40:\"HAuA200irzF63fgFw4vCVkrsZNuqTk6o2XLkHzlu\";s:9:\"_previous\";a:1:{s:3:\"url\";s:33:\"http://localhost:8000/security\";}s:5:\"flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:50:\"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d\";i:1;s:9:\"_sf2_meta\";a:3:{s:1:\"u\";i:1464957596;s:1:\"c\";i:1464957416;s:1:\"l\";s:1:\"0\";}}\";"

This output makes me assume that the redis option for storing sessions in laravel is working fine.

Next, for logging out a user from a specific session, I am using the following set of instructions:

public function logoutSession($session_id) {
     $redis = Redis::connection();
     $redis->del('laravel:' . $session_id);
     $redis->srem('user:sessions:' . Auth::user()->id, $session_id);
} 

Once this function is called, the corresponding session id is successfully deleted.

Running the SMEMBERS and GET commands again in redis-cli proves it.

So the scenario is, I try to delete a session opened in say, Firefox from another browser say, Chrome. Cliking on the logout link (for Firefox session from Chrome session) deletes the Firefox session from redis-server successfully, but if I try to refresh the Firefox browser, I am still logged in.

Just an image displaying the functionality I am trying to achieve

I cannot understand where I am going wrong exactly. Any sort of help will be highly appreciated.

Thanks

NOTE: I am already using the 'auth' middleware, so that cannot be the problem. Plus, if I try to debug the code, I am seeing different session_ids in $_COOKIE variable and http request variable. Is this normal?

  • I believe that You can find answer [here](http://stackoverflow.com/questions/37405740/laravel-5-2-how-to-logout-a-user-from-all-of-his-devices) – Giedrius Kiršys Jun 03 '16 at 13:27
  • If I am not wrong, the accepted answer in the link you provided basically uses the same logic, except, it logs out the user from all devices at once. In my case, I can see the sessions being deleted in redis-server but the user does not gets log out upon page refresh. – Mayank Chaudhary Jun 03 '16 at 13:35

1 Answers1

0

I had a similar issue once myself. I was frustrating myself with cache invalidation etc... and then after going through the "log in" process again I had forgotten to check for the "remember me" cookie.

https://laravel.com/docs/master/authentication#remembering-users

Turns out I had cleared the Cache successfully, but needed to call:

Auth::logout();

In order to remove the "remember_token" from the database. Otherwise, Laravel sees this as a valid way to reboot the Auth system, logging the user back in and setting a new session cookie.

Using your code:

public function logoutSession($session_id) {
    $redis = Redis::connection();
    $redis->del('laravel:' . $session_id);
    $redis->srem('user:sessions:' . Auth::user()->id, $session_id);
    Auth::logout();
}

But this logs out from ALL sessions, including the one you're working with.

For your problem, I propose using the Auth::viaRemember() method to determine if the client creating the request along with the cookie is the one you're currently operating with. It differentiates between your current session cookie and a "remember me" cookie:

if (Auth::viaRemember())
{
    // Check Redis for session info
    // Do something if not found, otherwise just proceed
}

**EDIT**: I found this after posting my answer: Laravel Auth::logout not removing remember me cookie

So to recap:

if (Auth::viaRemember())
{
    if (!Redis::get($key))
    {
        // Get remember_me cookie name
        $rememberMeCookie = Auth::getRecallerName();

        // Tell Laravel to forget this cookie
        $cookie = Cookie::forget($rememberMeCookie);

        return Redirect::to('/')->withCookie($cookie);
    }
}
Community
  • 1
  • 1
Justin Origin Broadband
  • 1,492
  • 1
  • 11
  • 14