title: How to list all logged-in users in Laravel and Redis?
body: <p>I'm currently making an app on Laravel (5.3) and require a list of all logged-in users. I was originally going to store them in MySQL but was advised that Redis would be better for the job. Once I looked at Redis docs I was going to store all the users in a set, but then realised you can't set an expire time on individual members, and so opted for namespaced strings instead.</p>
  
  <p>I have written some code that I believe is functioning correctly, but would like advice on improving it/fixing any problems there might be.</p>
  
  <p>So first, here are the two functions I added in LoginController.php</p>
  
  <pre><code>// Overriding the authenticated method from  Illuminate\Foundation\Auth\AuthenticatesUsers
  protected function authenticated(Request $request, $user)
  {
      $id = $user-&gt;id;
  
      // Getting the expiration from the session config file. Converting to seconds
      $expire = config('session.lifetime') * 60;
  
      // Setting redis using id as namespace and value
      Redis::SET('users:'.$id,$id);
      Redis::EXPIRE('users:'.$id,$expire);
  }
  
  //Overriding the logout method from Illuminate\Foundation\Auth\AuthenticatesUsers
  public function logout(Request $request)
  {
      // Deleting user from redis database when they log out
      $id = Auth::user()-&gt;id;
      Redis::DEL('users:'.$id);
  
      $this-&gt;guard()-&gt;logout();
  
      $request-&gt;session()-&gt;flush();
  
      $request-&gt;session()-&gt;regenerate();
  
      return redirect('/');
  }
  </code></pre>
  
  <p>Next I wrote Middleware called 'RefreshRedis' in order to refresh the expiration on the Redis when the user does something that refreshes their session.</p>
  
  <pre><code>public function handle($request, Closure $next)
  {
      //refreshing the expiration of users key
      if(Auth::check()){
          $id = Auth::user()-&gt;id;
          $expire = config('session.lifetime') * 60;
          Redis::EXPIRE('users:'.$id,$expire);
      }
      return $next($request);
  }
  </code></pre>
  
  <p>I then registered the Middleware in $middlewareGroups just after the StartSession Middleware</p>
  
  <pre><code>protected $middlewareGroups = [
      'web' =&gt; [
          \App\Http\Middleware\EncryptCookies::class,
          \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
          \Illuminate\Session\Middleware\StartSession::class,
          \App\Http\Middleware\RefreshRedis::class,
          \Illuminate\View\Middleware\ShareErrorsFromSession::class,
          \App\Http\Middleware\VerifyCsrfToken::class,
          \Illuminate\Routing\Middleware\SubstituteBindings::class,
      ],
  
      'api' =&gt; [
          'throttle:60,1',
          'bindings',
      ],
  ];
  </code></pre>
  
  <p>In order to get a list of all the users I used a modified version of the function found in <a href="https://stackoverflow.com/questions/35477172/laravel-and-redis-scan">this</a> thread.</p>
  
  <pre><code>class Team extends AbstractWidget
  {
  
  /**
   * Treat this method as a controller action.
   * Return view() or other content to display.
   */
  public function run()
  {
      //Find all logged users id's from redis
      $users = $this-&gt;loggedUsers('users:*');
  
      return view('widgets.team',compact('users'));
  }
  
  
  protected function loggedUsers($pattern, $cursor=null, $allResults=array())
  {
      // Zero means full iteration
      if ($cursor==="0"){
          $users = array ();
  
          foreach($allResults as $result){
              $users[] = User::where('id',Redis::Get($result))-&gt;first();
          }
          return $users;
      }
  
      // No $cursor means init
      if ($cursor===null){
          $cursor = "0";
      }
  
      // The call
      $result = Redis::scan($cursor, 'match', $pattern);
  
      // Append results to array
      $allResults = array_merge($allResults, $result[1]);
  
      // Get rid of duplicated values
      $allResults = array_unique($allResults);
  
      // Recursive call until cursor is 0
      return $this-&gt;loggedUsers($pattern, $result[0], $allResults);
  }
  }
  </code></pre>