我在哪里存储用户名和用户 ID?会话或饼干


Where do i store username and userid? sessions or cookie?

在我的代码中有许多实例需要快速访问登录的用户名和用户ID。 我目前使用饼干。 这不安全。

我以为会话将是一个解决方案,但会话过期。

另一种选择是在cookie中存储唯一令牌,然后与数据库中存储的令牌匹配,以检索登录的用户数据。 这是最安全的解决方案,但我看到的问题是,在我的代码中有很多时候需要登录的用户名和用户 ID,但一直查询会消耗不必要的资源(这是真的吗?

解决方案是什么?

我将尝试将评论中所说的所有内容合并为一个答案。因此,请通过投票来向其他有用的用户展示他们的爱!我还将简要概述会话的工作原理,以使答案对更广泛的受众有用。

当用户登录到网站时,将创建一个会话来识别他们。会话在 PHP 中通过创建会话 ID 进行处理,然后将该 ID 与服务器端的变量存储相关联,该变量存储在 PHP 脚本中使用$_SESSION超全局访问。会话 ID 存储在客户端的 Cookie 中,并标识其会话。

为了保持安全,会话 ID 必须是唯一的、随机的和秘密的。如果攻击者猜出您的会话 ID,他们可以使用相同的 ID 在自己的计算机上创建 cookie,并接管您的会话。他们会以您的身份登录!这显然是不好的,所以PHP使用一个强大的随机数生成器来创建这些会话ID。为了使事情更加安全,您可以在站点范围内启用SSL,并通知浏览器仅使用HTTPS标志通过SSL发送cookie。不过,这对您的网站来说可能是矫枉过正的。

为了防止泄露的会话 ID 永远有用,或者坏人在你去商店后潜入你的房间,会话使用超时。最好让它们在相当短的时间内过期 - 10 到 60 分钟,具体取决于您的安全要求。您可以在每次查看页面时重置超时,这样活动用户就不会注销。

为了允许用户被记住(即"记住我"复选框(,您需要提供一个用作身份验证令牌的 cookie。请记住,出于所有意图和目的,此令牌与拥有密码相同。这意味着如果坏人窃取了cookie,他们可以登录您的帐户。为了使此选项安全,我们可以使用一次性令牌。这些令牌应该是一次性的、随机的、长的和秘密的。将它们视为密码!

以下是实现它们的方法:

  1. 生成随机令牌。如果可以,请使用/dev/urandom,否则您需要从mt_rand中获得数百个值才能获得足够"随机"的内容,然后使用 SHA1 对生成的字符串进行哈希处理以生成令牌。
  2. 使用强密码哈希算法(例如 PBKDF2 或 bcrypt(来创建令牌的哈希。请勿将 SHA1 或 MD5 用于此目的 - 它们不是为散列密码而设计的!
  3. 将哈希以及它所属的用户的 ID 和创建日期插入到数据库表中。
  4. 在用户端的 Cookie 中设置令牌。
  5. 当用户访问网站、未登录并检测到登录令牌 cookie 时,使用您在步骤 2 中使用的相同算法对 cookie 中的令牌值进行哈希处理,并在数据库中查找。如果它与条目匹配,则以该 ID 登录用户。
  6. 从数据库中删除该条目并发出一个新条目(返回到步骤 1(。

您还应该运行一个脚本来查找非常旧的会话令牌(例如 3 个月或更长时间(并删除它们。这将要求用户在长时间不活动后返回时再次登录。

有关这方面的更详细解释,以及有关安全Web表单登录系统的更多重要信息,请阅读基于表单的网站身份验证权威指南并查看OWASP项目。

如果客户端上不需要它,请确保它不会在那里结束。

由于userId特定于登录用户而不是特定计算机,因此cookie似乎不是要走的路。

PHP 中的基本身份验证通常通过会话完成,因此您也可以将 userId 添加到会话中。

如果会话时间

太短,请增加会话时间。

我将此类信息存储在数据库中,并在启动时在我的全局对象注册表中创建一个用户对象。用户对象保存用户名或电子邮件等信息,并允许更改这些信息。登录状态本身存储在会话中,也存储在 cookie 中。