title: keeping track of login cookies between multiple devices
body: <p>So I just just built/hacked together my first cookie verification formula, and seems to work all-right, but have realized that it does not accommodate for when a user logs in on multiple devices, as well as one tester reporting slowness(which I cannot directly attest to the cookies). I do recognize a few possible means to solving the multiple device issue, but as I have never really used cookies before, I would like some expert opinion on the <strong>best</strong> way to handle this. If anyone has any other advice for my methods, they would be greatly appreciated, and I will almost certainly implement them before adding this a the header of each page. </p>
  
  <pre><code>function rememberMe() {
  
      $cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
  
      if ($cookie) {
            list ($username, $token, $mac) = explode(':', $cookie);
            if ($mac !== hash_hmac('sha256', $username . ':' . $token, XXXX)) {
                 return false;
            }
  
            function fetchTokenByUsername($username) {
                      $host="";
                      $dbusername="xxxx";
                      $dbpassword="xxxx";
                      $database="xxxx";
  
                      global $mysqli;
                      $stmt = $mysqli-&gt;prepare("SELECT username, token
                                                FROM cookielogin
                                                WHERE username=? //pull most recent cookie key from DB
                                                ORDER BY keyid DESC
                                                LIMIT 1");
                      $stmt-&gt;bind_param('s', $username);
                      if (!$stmt) {
                                   header('Location: login.php');
                                   die();
                                   }
                      $stmt-&gt;execute();
                      $stmt-&gt;store_result();
                      $stmt-&gt;bind_result($userjunk, $userToken);
                      $stmt-&gt;fetch();
                      return $userToken;
               }
  
               function logUserIn($username) {
                      $host="";
                      $dbusername="xxxx";
                      $dbpassword="xxxx";
                      $database="xxxx";
  
                      global $mysqli;
  
                      $active=1;
                      $stmt = $mysqli-&gt;prepare("SELECT id, email, username, password, gender, homelat, homelng, salt FROM users WHERE username=? AND active=?");
                      $stmt-&gt;bind_param('si', $username, $active);
                      $stmt-&gt;execute();
                      $stmt-&gt;store_result();
                      $stmt-&gt;bind_result($id, $email, $xusername, $xpassword, $gender, $homelat, $homelng, $salt);
                      $stmt-&gt;fetch();
                      if (!$stmt) {
                          header('Location: login.php');
                          die();
                      }
                      $numrows = $stmt-&gt;num_rows;
                      if ($numrows == 0) {
                          $_SESSION['loggedin'] = false;
                          $_SESSION['error'] = ("Incorrect username and password combination, please try to log in again");
                          exit();
                      }
                      session_regenerate_id(); // set session information
                      $_SESSION['sess_user_id'] = $id;
                      $_SESSION['sess_email'] = $email;
                      $_SESSION['sess_username'] = $xusername;
                      $_SESSION['sess_gender'] = $gender;
                      $_SESSION['sess_homelat'] = $homelat;
                      $_SESSION['sess_homelng'] = $homelng;
                      $_SESSION['loggedin'] = true;
                }
  
                function timingSafeCompare($userToken, $token) {
                      //removed for brevity (and pulled from a library, so I am confident in it's abilities)
                  }
  
                  $userToken = fetchTokenByUsername($username);
                  if (timingSafeCompare($userToken, $token) === 0) {
                           logUserIn($username);
                           return true;
                  }
             }
             else{
                     return false;
             }
      }
  
  if ((isset($_SESSION['sess_username']) and $_SESSION['sess_username'] != '') ||(rememberMe()== true)):
  </code></pre>
  
  <p>as you can see, I only check the users cookie against the most recently stored cookie key in my database. This is where multiple devices are an issue. My though was I could pull up the last 5 cookie keys from the database, build an array, then check if theirs is in the array. This doesn't seem fool proof by any means though.  I also supposed I could save each cookie with an ip address, but this would obviously fail under a VPN. 
  As for now, I only store the cookie key with the username, time of last use, and an auto increment column.</p>
  
  <p>Sincere thanks for any help. It is greatly appreciated. </p>