【问题标题】:PHP remember me cookiesPHP 记住我的 cookie
【发布时间】:2018-02-15 12:12:15
【问题描述】:

我正在尝试为用户登录创建一个记住我的功能。我想我已经涵盖了基础知识。

如果由于某种原因 auth_tokens 表应该被泄露,则通过使 cookie 值不等于表值 (base64_encode/base64_decode) 来防止模拟。 (它们可以被解码和使用,但窃取帐户至少需要更多的工作)

cookie 中不存储任何用户信息。

当用户使用记住我 cookie 成功登录时,会设置一个会话以防止数据库收到无用的请求。

每次登录时都会创建一个新的选择器、令牌和过期日期

所以我现在的问题是,有没有办法防止某人窃取 cookie 值,然后创建记住我的 cookie 以成功以该用户身份登录?

我使用会话的方式是安全的,还是有人可以将这些设置为他们想要的任何值?

还有我的最后一个问题。 AUTH_TOKENS 表中的 USER_ID 是否也应该进行编码,以便更难猜测令牌属于哪个用户?如果是这样,我将如何在需要时从用户表中选择正确的用户 ID。

if(auto login) {

    $expire = time() + 3600 * 24 * 30; // Cookie expire time
    $expire_encoded = base64_encode($expire); // Expire encoded

    $token_encoded = base64_encode(bin2hex(random_bytes(32))); // 32chars token encoded
    $token = base64_decode($token_encoded); // 32 chars token decoded

    $selector_encoded = base64_encode(bin2hex(random_bytes(16))); // 16 chars token encoded
    $selector = base64_decode($selector_encoded); // 16 chars token decoded

    $userid = 1; // User id
    $value = "$selector|$token"; // Cookie value

    setcookie('remember', $value, $expire, '/', $_SERVER['SERVER_NAME'], true); // Set cookie

    // Insert to db (not an actual function, just for this post. I'm using bind parm)
    insert_db(SELECTOR = $selector_encoded, USER_ID = $userid, TOKEN = $token_encoded, EXPIRES = $expire_encoded, IP = ip, date = date/time)

}

if((isset($_COOKIE['remember']) && (!isset($_SESSION['logged_in']))) {

    $tokens = explode('|',$_COOKIE['remember']);

    $selector = base64_encode($tokens[0]);
    $token = base64_encode($tokens[1]);

    // Select from db (not an actual function, just for this post. I'm using bind parm)
    $row = select_from_db(WHERE SELECTOR = $selector AND TOKEN = $token);

    if(mysqli_num_rows($row) === 1){

       // User logged in
       $_SESSION['logged_in'] = true;
       $_SESSION['user_id'] = $row['USER_ID'];

       // Generate new selector, token and expire date and insert to db

    } else {

      // User not logged in

    }

}

我的 auth_tokens 表是这样的

    +------------------+
    | AUTH_TOKENS      |
    +------------------+
    | ID               |
    | SELECTOR         |
    | USER_ID          |
    | TOKEN            |
    | EXPIRES          |
    | IP               |
    | DATE             |
    +------------------+

【问题讨论】:

  • 您可以通过将 IP 添加到您的令牌并结合用户名来添加额外的安全性。您还可以保存用户登录的 IP,以便检查 IP 和令牌是否匹配。
  • 是的,但是用户必须在每次更改 ip 时登录。我认为这违背了自动登录的目的。大多数人都有动态 ip。

标签: php cookies


【解决方案1】:

记住我的令牌不应通过 JavaScript 访问,也不应通过非安全请求传输。因此,如果是这种情况,某人如何访问令牌,如果他可以访问您的数据库,那就是另一个问题了。

因此,要使 cookie 仅通过 HTTPS 请求传输并隐藏它以防止通过 JavaScript 访问,您应该在代码中替换此行

setcookie('remember', $value, $expire, '/', $_SERVER['SERVER_NAME'], true);

用这个:

setcookie('remember', $value, $expire, '/', $_SERVER['SERVER_NAME'], true, true);

更多详情请阅读手册setcookie

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 2011-03-22
    • 1970-01-01
    • 2011-08-15
    • 2017-06-04
    • 2013-01-03
    • 2012-07-10
    • 1970-01-01
    相关资源
    最近更新 更多