我的 Web 应用程序使用会话来存储用户登录后的信息,并在用户在应用程序中从一个页面移动到另一个页面时维护该信息。在这个特定的应用程序中,我存储 user_id, first_namelast_name 的人。

我想在登录时提供一个“保持登录”选项,该选项将在用户的计算机上放置一个 cookie 两周,当他们返回应用程序时,将使用相同的详细信息重新启动他们的会话。

执行此操作的最佳方法是什么?我不想存储他们的 user_id 在 cookie 中,因为这似乎会让一个用户很容易尝试伪造另一用户的身份。

有帮助吗?

解决方案

好吧,让我直白地说:如果您出于此目的将用户数据或从用户数据派生的任何内容放入 cookie,那么您就做错了。

那里。我说了。现在我们可以继续讨论实际的答案。

您可能会问,对用户数据进行哈希处理有什么问题吗?好吧,这归结为暴露表面和通过默默无闻实现的安全性。

想象一下您是攻击者。您会在会话中看到为记住我而设置的加密 cookie。它的宽度为 32 个字符。哎呀。这可能是 MD5...

我们还假设他们知道您使用的算法。例如:

md5(salt+username+ip+salt)

现在,攻击者所需要做的就是暴力破解“盐”(这并不是真正的盐,稍后会详细介绍),他现在可以使用其 IP 地址的任何用户名生成他想要的所有假令牌!但是暴力破解盐很难,对吧?绝对地。但现代 GPU 非常擅长于此。除非你在其中使用足够的随机性(使其足够大),否则它会很快掉落,城堡的钥匙也会随之掉落。

简而言之,唯一能保护你的是盐,它并没有像你想象的那样真正保护你。

可是等等!

所有这一切都假设攻击者知道算法!如果它是秘密且令人困惑的,那么你就安全了,对吗? 错误的. 。这种思路有一个名字: 通过默默无闻实现安全, ,这应该 绝不 可以依靠。

更好的方法

更好的方法是永远不要让用户的信息离开服务器,除了 id 之外。

当用户登录时,生成一个大的(128 到 256 位)随机令牌。将其添加到数据库表中,该表将令牌映射到用户 ID,然后将其通过 cookie 发送到客户端。

如果攻击者猜到了另一个用户的随机令牌怎么办?

好吧,让我们在这里做一些数学计算。我们正在生成一个 128 位随机令牌。这意味着有:

possibilities = 2^128
possibilities = 3.4 * 10^38

现在,为了说明这个数字有多大,让我们想象一下互联网上的每台服务器(假设今天有 50,000,000 台)都试图以每秒 1,000,000,000 次的速度暴力破解该数字。实际上,您的服务器在这样的负载下会崩溃,但让我们来解决这个问题。

guesses_per_second = servers * guesses
guesses_per_second = 50,000,000 * 1,000,000,000
guesses_per_second = 50,000,000,000,000,000

所以每秒有 50 万亿次猜测。太快了!正确的?

time_to_guess = possibilities / guesses_per_second
time_to_guess = 3.4e38 / 50,000,000,000,000,000
time_to_guess = 6,800,000,000,000,000,000,000

所以 6.8 六万亿秒...

让我们尝试将其减少到更友好的数字。

215,626,585,489,599 years

或者甚至更好:

47917 times the age of the universe

是的,这是宇宙年龄的 47917 倍......

基本上不会被破解。

总结一下:

我推荐的更好的方法是用三部分来存储 cookie。

function onLogin($user) {
    $token = GenerateRandomToken(); // generate a token, should be 128 - 256 bit
    storeTokenForUser($user, $token);
    $cookie = $user . ':' . $token;
    $mac = hash_hmac('sha256', $cookie, SECRET_KEY);
    $cookie .= ':' . $mac;
    setcookie('rememberme', $cookie);
}

然后,验证:

function rememberMe() {
    $cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
    if ($cookie) {
        list ($user, $token, $mac) = explode(':', $cookie);
        if (!hash_equals(hash_hmac('sha256', $user . ':' . $token, SECRET_KEY), $mac)) {
            return false;
        }
        $usertoken = fetchTokenByUserName($user);
        if (hash_equals($usertoken, $token)) {
            logUserIn($user);
        }
    }
}

笔记:不要使用令牌或用户和令牌的组合来查找数据库中的记录。始终确保根据用户获取记录,并使用时间安全的比较函数来比较获取的令牌。 有关定时攻击的更多信息.

现在,是 非常 重要的是 SECRET_KEY 是一个加密秘密(由类似的东西生成 /dev/urandom 和/或源自高熵输入)。还, GenerateRandomToken() 需要是一个强随机源(mt_rand() 还不够强大。使用库,例如 随机库 或者 随机兼容, , 或者 mcrypt_create_iv()DEV_URANDOM)...

hash_equals() 是为了防止 定时攻击。如果您使用 PHP 5.6 以下的 PHP 版本,该函数 hash_equals() 不支持。在这种情况下,您可以更换 hash_equals() 使用timingSafeCompare函数:

/**
 * A timing safe equals comparison
 *
 * To prevent leaking length information, it is important
 * that user input is always used as the second parameter.
 *
 * @param string $safe The internal (safe) value to be checked
 * @param string $user The user submitted (unsafe) value
 *
 * @return boolean True if the two strings are identical.
 */
function timingSafeCompare($safe, $user) {
    if (function_exists('hash_equals')) {
        return hash_equals($safe, $user); // PHP 5.6
    }
    // Prevent issues if string length is 0
    $safe .= chr(0);
    $user .= chr(0);

    // mbstring.func_overload can make strlen() return invalid numbers
    // when operating on raw binary strings; force an 8bit charset here:
    if (function_exists('mb_strlen')) {
        $safeLen = mb_strlen($safe, '8bit');
        $userLen = mb_strlen($user, '8bit');
    } else {
        $safeLen = strlen($safe);
        $userLen = strlen($user);
    }

    // Set the result to the difference between the lengths
    $result = $safeLen - $userLen;

    // Note that we ALWAYS iterate over the user-supplied length
    // This is to prevent leaking length information
    for ($i = 0; $i < $userLen; $i++) {
        // Using % here is a trick to prevent notices
        // It's safe, since if the lengths are different
        // $result is already non-0
        $result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i]));
    }

    // They are only identical strings if $result is exactly 0...
    return $result === 0;
}

其他提示

安全通知:根据cookie关MD5hash的确定性数据是一个糟糕的想法;这是更好地利用随机的令牌来自CSPRNG.看看 ircmaxell的答案 这个问题对一个更安全的办法。

通常我做这样的事情:

  1. 用户登录在与'让我登录在
  2. 创建届会议
  3. 创建一个饼干所谓的东西含有:md5(盐+用户名+ip+盐)和一个叫cookie somethingElse含id
  4. 存储cookie在数据库
  5. 用户不会的东西和叶子----
  6. 用户回返、检查somethingElse饼干,如果存在,获得旧的散列从数据库的用户,检查的内容饼干事配合的散列从数据库,该数据库还应配有一个新计算的散列(ip)因此:cookieHash==databaseHash==md5(盐+用户名+ip+盐),如果他们这样做,转到2,如果他们不goto1

当然您可以使用不同cookie名称等。你也可以改变的内容cookie一点,只需确保它不是容易地创建。例如,您可以创建一个user_salt当用户创建和也把在该cookie。

你也可以使用sha1而不是md5(或几乎任何算法)

介绍

你的标题 "让我登录"-最好的办法 很难让我知道从哪里开始,因为如果你是在寻找最佳办法,然后将审议如下:

  • 识别
  • 安全

饼干

饼干是脆弱的,之间通用浏览器cookie盗脆弱性和跨站脚本攻击我们必须接受这个饼干都不安全。帮助改善安全,你必须注意, php setcookies 有额外的功能,例如:

bool setcookie (string$name[、string$value[,int$期=0[、string$path[、string$域[、bool $安全 =false[、bool $httponly =false]]]]]])

  • 安全(采用HTTPS connection)
  • httponly(降低身份盗窃通过的XSS攻击)

定义

  • 令牌(不可预知的随机的字符串n长。/dev/urandom)
  • 基准(不可预知的随机的字符串n长。/dev/urandom)
  • 签署(产生键的散列值使用HMAC方法)

简单的方法

一个简单的解决方案将是:

  • 用户登录上还记得我
  • 登录Cookie发出的令牌和签名
  • 当时是回国,签名是检查
  • 如果署名是好的..然后用户名和标记是看起来在数据库
  • 如果没有有效的..回到登录网页
  • 如果有效的自动登录

上述案例研究概括了所有给出的例子,在这一页但他们缺点是

  • 有没有办法知道如果饼干被偷了
  • 攻击者,可以访问敏感的行动,如改变口令或数据,如个人和烘烤的信息等。
  • 受害cookie仍然是有效的饼干寿命

更好的解决方案

一个更好的解决方案将会是

  • 用户登录在记得我选择
  • 产生令牌和签名和存储在饼干
  • 标记是随机的,仅适用于单autentication
  • 令牌替换在每次访问的网站
  • 当一个非登录用户访问该网站的签字、标记和验证用户名
  • 还记得我登录应具有有限的访问和不允许修改密码、个人的信息等。

例码

// Set privateKey
// This should be saved securely 
$key = 'fc4d57ed55a78de1a7b31e711866ef5a2848442349f52cd470008f6d30d47282';
$key = pack("H*", $key); // They key is used in binary form

// Am Using Memecahe as Sample Database
$db = new Memcache();
$db->addserver("127.0.0.1");

try {
    // Start Remember Me
    $rememberMe = new RememberMe($key);
    $rememberMe->setDB($db); // set example database

    // Check if remember me is present
    if ($data = $rememberMe->auth()) {
        printf("Returning User %s\n", $data['user']);

        // Limit Acces Level
        // Disable Change of password and private information etc

    } else {
        // Sample user
        $user = "baba";

        // Do normal login
        $rememberMe->remember($user);
        printf("New Account %s\n", $user);
    }
} catch (Exception $e) {
    printf("#Error  %s\n", $e->getMessage());
}

类使用

class RememberMe {
    private $key = null;
    private $db;

    function __construct($privatekey) {
        $this->key = $privatekey;
    }

    public function setDB($db) {
        $this->db = $db;
    }

    public function auth() {

        // Check if remeber me cookie is present
        if (! isset($_COOKIE["auto"]) || empty($_COOKIE["auto"])) {
            return false;
        }

        // Decode cookie value
        if (! $cookie = @json_decode($_COOKIE["auto"], true)) {
            return false;
        }

        // Check all parameters
        if (! (isset($cookie['user']) || isset($cookie['token']) || isset($cookie['signature']))) {
            return false;
        }

        $var = $cookie['user'] . $cookie['token'];

        // Check Signature
        if (! $this->verify($var, $cookie['signature'])) {
            throw new Exception("Cokies has been tampared with");
        }

        // Check Database
        $info = $this->db->get($cookie['user']);
        if (! $info) {
            return false; // User must have deleted accout
        }

        // Check User Data
        if (! $info = json_decode($info, true)) {
            throw new Exception("User Data corrupted");
        }

        // Verify Token
        if ($info['token'] !== $cookie['token']) {
            throw new Exception("System Hijacked or User use another browser");
        }

        /**
         * Important
         * To make sure the cookie is always change
         * reset the Token information
         */

        $this->remember($info['user']);
        return $info;
    }

    public function remember($user) {
        $cookie = [
                "user" => $user,
                "token" => $this->getRand(64),
                "signature" => null
        ];
        $cookie['signature'] = $this->hash($cookie['user'] . $cookie['token']);
        $encoded = json_encode($cookie);

        // Add User to database
        $this->db->set($user, $encoded);

        /**
         * Set Cookies
         * In production enviroment Use
         * setcookie("auto", $encoded, time() + $expiration, "/~root/",
         * "example.com", 1, 1);
         */
        setcookie("auto", $encoded); // Sample
    }

    public function verify($data, $hash) {
        $rand = substr($hash, 0, 4);
        return $this->hash($data, $rand) === $hash;
    }

    private function hash($value, $rand = null) {
        $rand = $rand === null ? $this->getRand(4) : $rand;
        return $rand . bin2hex(hash_hmac('sha256', $value . $rand, $this->key, true));
    }

    private function getRand($length) {
        switch (true) {
            case function_exists("mcrypt_create_iv") :
                $r = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
                break;
            case function_exists("openssl_random_pseudo_bytes") :
                $r = openssl_random_pseudo_bytes($length);
                break;
            case is_readable('/dev/urandom') : // deceze
                $r = file_get_contents('/dev/urandom', false, null, 0, $length);
                break;
            default :
                $i = 0;
                $r = "";
                while($i ++ < $length) {
                    $r .= chr(mt_rand(0, 255));
                }
                break;
        }
        return substr(bin2hex($r), 0, $length);
    }
}

测试在火狐&铬

enter image description here

优点

  • 更好的安全
  • 限制访问于攻击者
  • 当cookie被盗,其唯一有效的单的访问
  • 当下一个原来的用户访问的网站,你可以自动检测和通知用户的盗窃

缺点

  • 不支持持续的连接,通过多浏览器(手机和网络)
  • Cookie仍可能被盗,因为用户只能得到的通知之后的下一个登录。

速战速决

  • 引进审批系统的各个系统,该系统必须具有持续的连接
  • 使用多种饼干用于认证

多Cookie的方法

如果攻击者是关于窃取饼干的只关注它在一个特定网站或领域,例如。 example.com

但你真的可以进行身份验证用户的2个不同的领域(example.com & fakeaddsite.com),并使它看起来像"的广告饼干"

  • 用户登录到 example.com 记住我
  • 储存用户名,标记,参考在饼干
  • 储存用户名,标记,参考数据库。缓存
  • 送做参考id通过获得和框架, fakeaddsite.com
  • fakeaddsite.com 使用的参考取用户和标记数据库
  • fakeaddsite.com 商店的签名
  • 当用户返回取签名的信息与从框架fakeaddsite.com
  • 将它的数据和做证
  • .....你知道剩下的

有些人可能不知道怎么可能使用2种不同的曲奇饼吗?及其可能的,想象一下 example.com = localhostfakeaddsite.com = 192.168.1.120.如果你检查的饼干就是这样的

enter image description here

从图像上面的

  • 目前网站的访问是localhost
  • 它还包含设置的cookie从192.168.1.120

192.168.1.120

  • 只接受的定义 HTTP_REFERER
  • 只接受的连接从指定 REMOTE_ADDR
  • 没有JavaScript,没有内容,但是由没有什么,而不是注册信息以及添加或检索它从饼干

优点

  • 99%的时间,你有骗攻击者
  • 你可以很容易地锁定的帐户在攻击者的第一次尝试
  • 攻击能够阻止,甚至在下一次登录像其他的方法

缺点

  • 多请求到服务器只是为一个单一登录

改善

  • 做了使用框架使用 ajax

有两个非常有趣的文章,我发现,同时寻找一个完美的解决方案"记住我"-的问题:

我在这里问的一个角度>,答案会带你到你需要的所有基于令牌的时机退出cookie链接。

基本上,你不存储在cookie中的用户ID。您存储该用户所使用的回升旧登录会话一次性令牌(巨大的字符串)。然后使其真正安全的,你问的重操作的密码(例如变更密码本身)。

我会建议由斯特凡提到的方法(即遵循href="http://jaspan.com/improved_persistent_login_cookie_best_practice" rel="noreferrer">改进永久登录cookie最佳实践在的HttpOnly饼干所以它们不是可访问的,潜在的恶意,JavaScript的。

生成一个散列,只有你知道的,然后将其存储在您的数据库,以便它可以与用户相关联的秘密也许。如果工作得非常好。

旧线,但仍然是一个有效的担忧。我注意到一些良好的反应有关的安全,并避免使用的'安全通过默默无闻的',但实际的技术方法鉴别不足以在我的眼睛。事情我必须说,在我做出贡献我的方法:

  • 从来没有 商店密码在明确的文字...永远!
  • 从来没有 存储用户的散列的密码在一个以上的位置在你的数据库。你的后端服务器总是能够拉的散列的密码从用户的表格。这不是更有效的储存中的冗余数据代替的额外DB交易,反是真实的。
  • 你Session ID的应该是独特的,因此,没有两个用户可能会 曾经 共享一个ID,因此目身份证(可能你的驾驶许可证ID数没有匹配的另一个人?没有。) 这产生一两件的独特组合,基于2唯一串。你的话表应该使用的标识作为PK。许多设备可信任的自动登录,使用的另一个表对可信的设备,其中包含该清单的所有设备进行验证(见我下面的例子),并且是映射使用用户名。
  • 它没有任何目的,已知的散列的数据纳入一个cookie,cookie可以复制。我们正在寻找的是一种符合用户设备提供正规的信息,不能得到没有攻击影响用户的机器(同样,看到我的实例)。这将意味着,然而,合法用户谁禁止他机的静态的信息(即MAC地址、设备hostname,简,如果限制通过浏览器等。) 从剩余的一致(或欺骗它放在第一位)将不能使用这一特征。但是,如果这是一个关切的是,考虑事实上,你正在提供自动登录用户是谁 确定自己独特的, 所以如果他们拒绝已知通过欺骗自己的MAC,欺骗他们的简、欺骗/改变他们的主机名,躲在后面代理,等等, 然后他们不可识别的,而且永远不应该认证用于自动服务。如果你想要这个,你需要看成智能卡的访问捆绑在一起的客户端的软件,规定标识设备被使用。

所有被所述,有两大方面有自动登录在您的系统。

第一,便宜、简单的方法,把它所有的其他人。如果你让你的网站支持记录日志,说,你的帐户,则可能有一个简化的谷歌按钮,将日志中的用户如果他们已经签署成为谷歌(我在这里要回答这个问题,因为我总是签署成为谷歌).如果你希望用户将自动登录如果他们已经签署了在一个受信任和支持身份验证,以及检查箱子这样做,你客户的侧脚本执行代码对应的登录在按钮在装货之前,只要确保服务器储存的唯一标识在一个自动登录表,具有用户名,session ID,和认证方使用的用户。由于这些登录方法使用的AJAX,你是在等待一个响应,无论如何,这种反应是经过验证的响应或拒绝。如果你得到验证的响应,把它作为正常,然后继续载入的用户登录作为正常的。否则,登录失败,但是不要告诉用户,只要继续为尚未登录,他们会通知。这是为了防止攻击者是谁偷了饼干(或伪造他们在试图升级权限)从学习的用户自动登入该网站。

这是便宜,并可能也被认为是肮脏的一些,因为它试图以验证你可能已经签署了在自带的地方,如谷歌、Facebook,甚至没有告诉你。它应该,但是,不能使用的用户不要求自动签到你的网站,这个特定的方法是,仅用于外部认证,如与谷歌或FB。

因为外部认证是用来告诉服务器的场景背后的用户是否是经过验证,攻击者不能获得任何其他唯一标识,这是无用自己。我将阐述:

  • 用户'乔'的访问网站第一次会议ID放在cookie'届会'.
  • 用户'乔'的日志中,升级的特权、获得新的Session ID并重申cookie'届会'.
  • 用户'乔'选举产生自动登录使用谷歌,获得一个独特的ID放在cookie'keepmesignedin'.
  • 用户'乔'有谷歌让它们在签订,允许您的网站自动登录用户使用谷歌在你的后台。
  • 攻击者系统地试图独特的Id'keepmesignedin'(这是公共知识交给了每一个用户),而不是签署成为其他地方;试图独特的ID给予'乔'.
  • 服务器收到的唯一ID'乔',拉比赛中DB为一个谷歌的帐户。
  • 服务器发送攻击者登录网页运行的一个阿贾克斯的请求谷歌登录。
  • 谷歌的服务器接收到请求时,使用其API来看攻击者是不是记录在目前。
  • 谷歌送回应,也没有目前登录用户超过该连接。
  • 攻击者的网页收到的响应,剧本会自动重定向到登录网页有一个职位值的编码的网址。
  • 登录的页面获取的职位值,发送cookie'keepmesignedin'空值和有效期至日期1-1-1970阻止一个自动的尝试,造成攻击者的浏览器为简单地删除。
  • 攻击者给予正常的首次登录网页。

不管是什么,即使攻击者使用的一个ID,不存在,尝试失败的所有尝试除了当一个验收到响应。

这种方法可以应用于与您的内部认证方对于那些登录到网站的使用外部认证者。

=========

现在,你自己的认证系统,该系统可以自动登录用户,这是我如何做到这一点:

DB有几个表格:

TABLE users:
UID - auto increment, PK
username - varchar(255), unique, indexed, NOT NULL
password_hash - varchar(255), NOT NULL
...

注意的用户名是能够被255个字符长。我有我的服务器节目的限制的用户名在我的系统的32个字符,但外部认证程序可能具有的用户名与他们@域。顶级域名是比较大,所以我只是支持最长的一封电子邮件地址,用于最大的兼容性。

TABLE sessions:
session_id - varchar(?), PK
session_token - varchar(?), NOT NULL
session_data - MediumText, NOT NULL

注意,没有任何用户领域在这个表格中,因为用户名,当登录在会议的数据和程序不允许空数据。该session_id和session_token可产生使用random md5hash,sha1/128/256哈希、时间戳随机的字符串中加入到他们然后散列,或者无论你怎么想,但熵你的输出应该保持高,因为容忍,以减轻暴力攻击甚至离开该地,和所有哈希产生的会话课应该是检查匹配的会议桌之前试图增加他们。

TABLE autologin:
UID - auto increment, PK
username - varchar(255), NOT NULL, allow duplicates
hostname - varchar(255), NOT NULL, allow duplicates
mac_address - char(23), NOT NULL, unique
token - varchar(?), NOT NULL, allow duplicates
expires - datetime code

MAC地址通过其性质应该是独特的,因此它是有道理的,每个条目都有一个独特的价值。主机名称,另一方面,可能是重复的独立网络合法的。有多少人使用"家庭PC"作为他们的一个计算机名字?用户名是从会议数据通过服务后台的,所以操纵这是不可能的。作为标记,同的方法生成会议的代币的网页应使用来产生令牌在饼干用户自动登录.最后,日期时间代码加入时用户将需要重新验证他们的全权证书。更新这一日期时间上的用户登录保持它在几天内,或迫使其到期,而不管最后的登录保持这只一个月左右,无论你的设计规定。

这防止有人从系统地欺骗MAC和主机名用户他们知道自动的迹象。 从来没有 有的用户保持一cookie与他们密码,明文或以其他方式。有令牌可再生的每一页上的航行,只是因为你将本届会议的标记。这大大降低了可能性,攻击者能获得有效的令牌饼干,并使用它登录。有些人会说,攻击者可能偷cookie从受害者和做届会议重攻击中登录。如果攻击者可能会窃取的饼干(这是可能的),他们肯定会受到损害整个的设备,这意味着它们可能只使用的设备登陆无论如何,它击败的目的偷窃饼干。只要你站运行在HTTPS(其应当处理的密码,CC号,或其他登录系统),提供所有的保护的用户,你可以在一个浏览器。

有一点要记住:届会数据不应该到期,如果使用自动登录.你可以期能够继续本届会议虚假的,但是验证进入该系统应当恢复该届会议数据,如果是持续性的数据是预期继续会议之间。如果你想要这两种持久性和非持久性届会的数据,使用另一种表对持久性会议的数据与用户名为PK,并将服务器获取它喜欢它会正常届会的数据,只需使用另一个变量。

一次登录已经被以这种方式实现,服务器仍应验证本届会议。在这里,你可以代码的期望对于被盗或被破坏的系统;模式和其他预期结果的登录到会议的数据经常可以导致结论,系统被劫持或饼干是伪造的为了获得访问。这是您的国际空间站的科技可以把规则,这将触发一个账户锁定或自动清除的用户从自动登录系统,保持攻击了足够长的时间为用户确定如何攻击者,成功地以及如何把它们切断。

作为一个关注,是确保任何恢复尝试、密码改变,或登录失败的过去的阈值结果在自动登录被禁止,直到用户的验证适当地承认这已经发生。

我很抱歉,如果任何人期待码能给出我的答案,那是不会发生在这里。我会说,我使用PHP。和阿贾克斯给我的网站,并且我从未使用的Windows服务器...过。

我的解决方案是这样的。这不是100%的防弹但我认为这将节省您的大多数情况下。

当用户登录在成功地创建一个字符串这样的信息:

$data = (SALT + ":" + hash(User Agent) + ":" + username 
                     + ":" + LoginTimestamp + ":"+ SALT)

加密 $data, ,设置类型 HttpOnly 并设置的cookie。

当用户回到你的网站,使这一步骤:

  1. 拿到饼干的数据。删除危险的人物内的cookie。炸开它 : 符。
  2. 检查有效性。如果cookie是年龄超过X天,然后向用户登录网页。
  3. 如果饼干是不是老;获得最新的更改密码的时间从数据库。如果密码被改变后用户的最后一次登录向用户登录网页。
  4. 如果通过并不改变最近;获得用户的当前浏览器代理。检查是否(currentUserAgentHash==cookieUserAgentHash).如果代理同转到下一个步骤,还将登录网页。
  5. 如果所有步骤,通过成功地授权的用户名。

如果用户signouts,消除这种饼干。创造新的饼干,如果用户重新登录。

我不理解这个概念的存放加密的东西在一个饼干当的加密版本,你需要做的你的黑客攻击。如果我失去了一些东西,请评论。

我想到的是关于采取这种方式来记住我。如果你能看到任何问题,请评论。

  1. 创建一个表来储存"记住我"数据在单独的用户表,这样我可以登录在从多个设备。

  2. 成功登录(与记得我打勾):

    a)生成一种独特的随机的字符串中使用作为UserID在这台机器:bigUserID

    b)生成一种独特的随机的字符串:bigKey

    c)储存cookie:bigUserID:bigKey

    d)在"记住我"的表格,增加一个记录:UserID,IP地址,bigUserID,bigKey

  3. 如果试图访问东西那就需要登录:

    a)检查cookie和搜索bigUserID&bigKey有匹配的IP地址

    b)如果你找到它,日志的人而设置一个标志用户表中的"软登录",因此,对于任何危险的操作,可以提供一个完整的登录。

  4. 上注销的标记,所有"记住我"记录用户作为过期。

唯一的漏洞,我可以看到;

  • 你可以拿别人的笔记本电脑和欺骗他们的IP地址的cookie。
  • 你可以欺骗一个IP地址不同,每次和猜猜整个事情-但是有两个大串相匹配,这将是...做一个类似的计算以上...我不知道...巨大的几率有多大?

我看了所有的答案,仍然发现难以提取了我应该做的。如果一张图片胜过1K字我希望这可以帮助其他人实现基于巴里Jaspan的改进永久登录cookie最佳实践安全的永久存储

“在这里输入的图像描述”

如果您有任何疑问,意见或建议,我会尝试更新图表,以反映新手试图执行一个安全的永久登录。

实现一个“记住我的登录”功能,意味着你需要确切地定义什么那将意味着给用户。在最简单的情况下,我会用这意味着会话具有更长的超时时间:2天(说)而不是2小时。要做到这一点,你需要自己的会话存储,可能在数据库中,这样你就可以对会话数据设置自定义的到期时间。然后,你需要确保你设置一个Cookie,将坚持围绕几天(或更长),而不是到期时,他们关闭浏览器。

我能听到你问:“为什么2天?为什么不是2星期?”。这是因为使用PHP中的会话会自动将到期回来。这是因为一个会话在PHP到期实际上是一个空闲超时。

现在,话虽如此,我可能会实现,我存储在会议本身较硬的超时值,并进行2周左右的时间,并添加代码看到并强行无效会话。或者至少登录出来。这将意味着,用户将被要求定期登录。雅虎执行此操作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top