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

时间:2012-07-18 11:41:56

标签: php

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

我认为会议将是一个解决方案,但会议到期。

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

解决方案是什么?

3 个答案:

答案 0 :(得分:5)

我将尝试将评论中所说的所有内容合并为一个答案。因此,请通过upvoting他们的答案/评论向其他有用的用户展示一些爱!我还将简要介绍会议的工作方式,使答案对更广泛的受众有用。

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

为了保持安全,会话ID必须是唯一的,随机的和秘密的。如果攻击者猜测您的会话ID,他们可以使用相同的ID在自己的计算机上创建cookie,并接管您的会话。他们会像你一样登录!这显然很糟糕,因此PHP使用强大的随机数生成器来创建这些会话ID。为了使事情更安全,您可以在站点范围内启用SSL,并通知浏览器只使用HTTPS发送cookie,使用仅HTTPS标志。不过,这可能对您的网站来说太过分了。

为了防止泄露的会话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)。
  7. 您还应该运行一个查找非常旧的会话令牌(例如3个月或更长时间)的脚本并删除它们。这将要求用户在长时间不活动后返回时再次登录。

    如需更深入的解释,以及有关安全网络表单登录系统的更多重要信息,请阅读The Definitive Guide to Forms-Based Website Authentication并查看OWASP project

答案 1 :(得分:3)

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

由于userId特定于登录用户而非特定计算机,因此cookie似乎不太适合。

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

如果会话时间太短,请增加会话时间。

答案 2 :(得分:-4)

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