跟踪多个设备之间的登录cookie

时间:2015-01-15 21:01:07

标签: php authentication cookies login mysqli

所以我刚刚构建/黑客攻击了我的第一个cookie验证公式,似乎工作正常,但已经意识到它不适应用户登录多个设备时,以及一个测试报告缓慢(我不能直接证明饼干)。我确实认识到解决多个设备问题的一些可能方法,但由于我以前从未真正使用过cookie,所以我想就最佳方式来处理这个问题。如果有人对我的方法有任何其他建议,他们将不胜感激,我几乎肯定会在添加每个页面的标题之前实现它们。

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->prepare("SELECT username, token
                                              FROM cookielogin
                                              WHERE username=? //pull most recent cookie key from DB
                                              ORDER BY keyid DESC
                                              LIMIT 1");
                    $stmt->bind_param('s', $username);
                    if (!$stmt) {
                                 header('Location: login.php');
                                 die();
                                 }
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result($userjunk, $userToken);
                    $stmt->fetch();
                    return $userToken;
             }

             function logUserIn($username) {
                    $host="";
                    $dbusername="xxxx";
                    $dbpassword="xxxx";
                    $database="xxxx";

                    global $mysqli;

                    $active=1;
                    $stmt = $mysqli->prepare("SELECT id, email, username, password, gender, homelat, homelng, salt FROM users WHERE username=? AND active=?");
                    $stmt->bind_param('si', $username, $active);
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result($id, $email, $xusername, $xpassword, $gender, $homelat, $homelng, $salt);
                    $stmt->fetch();
                    if (!$stmt) {
                        header('Location: login.php');
                        die();
                    }
                    $numrows = $stmt->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)):

如您所见,我只根据我数据库中最近存储的cookie密钥检查用户cookie。这是多个设备存在问题的地方。我虽然可以从数据库中提取最后5个cookie密钥,然后构建一个数组,然后检查它们是否在数组中。尽管如此,这似乎并不是万无一失的证明。我还想我可以用ip地址保存每个cookie,但这显然会在VPN下失败。 至于现在,我只存储cookie密钥,其中包含用户名,上次使用时间和自动增量列。

真诚地感谢您的帮助。非常感谢。

1 个答案:

答案 0 :(得分:0)

您可以在您的select语句中添加Cookie的标记作为条件:

<?php
            $stmt = $mysqli->prepare("SELECT username, token
                                      FROM cookielogin
                                      WHERE username=? //pull most recent cookie key from DB
                                      AND token=?
                                      ORDER BY keyid DESC
                                      LIMIT 1");
            $stmt->bind_param('ss', $username, $token);

允许您为每个设备使用不同的Cookie。