简体   繁体   English

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

[英]Where do i store username and userid? sessions or cookie?

There are many instances in my code where quick access to the logged in username and userid is needed. 我的代码中有许多实例需要快速访问登录的用户名和用户ID。 I currently use cookies. 我目前使用cookies。 This isn't secure. 这不安全。

I thought sessions would be a solution but sessions expire. 我认为会议将是一个解决方案,但会议到期。

Another option, is to store a unique token in a cookie and then match with a stored token in the database, to retrieve logged in user data. 另一种选择是将唯一令牌存储在cookie中,然后与数据库中存储的令牌匹配,以检索登录的用户数据。 This is the most secure solution but the problem i see with this is, there are many times in my code where the logged in username and userid is needed but querying all the time would use up resources unnecessary(is this true?) 这是最安全的解决方案,但我看到的问题是,在我的代码中有很多次需要登录的用户名和用户ID,但是一直查询会占用资源不必要(这是真的吗?)

What is the solution? 解决办法是什么?

I'm going to try to coalesce everything that's been said in the comments into one answer. 我将尝试将评论中所说的所有内容合并到一个答案中。 As such, please show other helpful users some love by upvoting their answers / comments! 因此,请通过upvoting他们的答案/评论向其他有用的用户展示一些爱! I'm also going to give a brief overview of how sessions work, to make the answer useful to a wider audience. 我还将简要介绍会话的工作原理,使答案对更广泛的受众有用。

When a user logs into a website, a session is created to identify them. 当用户登录网站时,会创建会话以识别它们。 Sessions are handled in PHP by creating a session ID, then associating that ID with a variable store on the server side, which is accessed in PHP scripts using the $_SESSION superglobal. 通过创建会话ID,然后将该ID与服务器端的变量存储相关联,在PHP中处理会话,可以使用$_SESSION超全局在PHP脚本中访问该存储。 The session ID is stored in a cookie on the client-side, and identifies their session. 会话ID存储在客户端的cookie中,并标识其会话。

In order to remain secure, the session ID must be unique, random and secret. 为了保持安全,会话ID必须是唯一的,随机的和秘密的。 If an attacker guesses your session ID, they can create a cookie on their own computer using that same ID, and take over your session. 如果攻击者猜测您的会话ID,他们可以使用相同的ID在自己的计算机上创建cookie,并接管您的会话。 They'd be logged in as you! 他们会像你一样登录! This is obviously bad, so PHP uses a strong random number generator to create those session IDs. 这显然很糟糕,因此PHP使用强大的随机数生成器来创建这些会话ID。 In order to make things more secure, you can enable SSL site-wide and inform the browser to only ever send the cookie over SSL, using the HTTPS-only flag. 为了使事情更安全,您可以在站点范围内启用SSL,并通知浏览器只使用HTTPS发送cookie,使用仅HTTPS标志。 This might be overkill for your site, though. 不过,这可能对您的网站来说太过分了。

In order to prevent leaked session IDs from being useful forever, or bad guys sneaking into your room after you've gone out to the shop, sessions use timeouts. 为了防止泄露的会话ID永远有用,或者在你去商店后坏人潜入你的房间,会话使用超时。 It is best to have them expire after a reasonably short time - between 10 and 60 minutes depending on your security requirements. 最好让它们在相当短的时间后过期 - 根据您的安全要求,在10到60分钟之间。 You can reset the timeout every time you view the page, so an active user doesn't get logged out. 您可以在每次查看页面时重置超时,因此活动用户不会被注销。

In order to allow the user to be remembered (ie the "remember me" checkbox), you need to provide a cookie that works as an authentication token. 为了让用户能够被记住(即“记住我”复选框),您需要提供一个用作身份验证令牌的cookie。 Keep in mind that this token is, for all intents and purposes, the same as having your password. 请记住,出于所有意图和目的,此令牌与拥有密码相同。 This means that if the bad guy steals the cookie, they can log into your account. 这意味着如果坏人窃取了cookie,他们就可以登录您的帐户。 In order to make this option safe, we can use a one-time token. 为了使此选项安全,我们可以使用一次性令牌。 These tokens should be single-use, random, long and secret. 这些令牌应该是一次性的,随机的,冗长的和秘密的。 Treat them as if they were passwords! 把它们视为密码!

Here's how to implement them: 以下是如何实现它们:

  1. Generate a random token. 生成随机令牌。 Use /dev/urandom if you can, otherwise you need several hundred values from mt_rand to get something "random" enough, then hash the resulting string with SHA1 to produce the token. 如果可以的话,使用/dev/urandom ,否则你需要mt_rand几百个值来获得足够“随机”的东西,然后用SHA1散列生成的字符串以产生令牌。
  2. Use a strong password hashing algorithm (eg PBKDF2 or bcrypt) to create a hash of the token. 使用强密码散列算法(例如PBKDF2或bcrypt)来创建令牌的散列。 Do not use SHA1 or MD5 for this purpose - they are NOT designed for hashing passwords! 不要将SHA1或MD5用于此目的 - 它们不是为散列密码而设计的!
  3. Insert the hash into a database table, along with the ID of the user it belongs to and the date it was created. 将哈希值与其所属用户的ID及其创建日期一起插入数据库表。
  4. Set the token in a cookie on the user's side. 在用户侧的cookie中设置令牌。
  5. When the user visits the site, is not logged in, and a login token cookie is detected, hash the token value from the cookie using the same algorithm you used in step 2, and look it up in the database. 当用户访问该站点时,未登录,并且检测到登录令牌cookie,使用您在步骤2中使用的相同算法从cookie中散列令牌值,并在数据库中查找。 If it matches an entry, log the user in as that ID. 如果它与条目匹配,请将该用户作为该ID记录。
  6. Delete the entry from the database and issue a new one (back to step 1). 从数据库中删除该条目并发出一个新条目(返回步骤1)。

You should also run a script that looks for very old session tokens (eg 3 months or more) and delete them. 您还应该运行一个查找非常旧的会话令牌(例如3个月或更长时间)的脚本并删除它们。 This will require the user to log in again when they come back after a long period of inactivity. 这将要求用户在长时间不活动后返回时再次登录。

For a longer explanation of this, and many more important bits of information about secure web form login systems, read The Definitive Guide to Forms-Based Website Authentication and take a look at the OWASP project . 有关此问题的更长说明以及有关安全Web表单登录系统的更多重要信息,请阅读基于表单的网站身份验证的权威指南并查看OWASP项目

If it is not needed on the client, make sure it does not end up there. 如果客户端不需要它,请确保它不会在那里结束。

Since userId's are specific to a logged in user and not a specific computer, a cookie does not seem like the way to go. 由于userId特定于登录用户而不是特定计算机,因此cookie似乎不太适合。

Basic authentication in PHP is usually done with sessions, so you could just as well add the userId to the session. PHP中的基本身份验证通常使用会话完成,因此您也可以将userId添加到会话中。

If the session times are too short, increase the session time. 如果会话时间太短,请增加会话时间。

I store such information in a database and on startup create a user object in my global object-registry. 我将这些信息存储在数据库中,并在启动时在我的全局对象注册表中创建一个用户对象。 The user object holds information like user-name or e-mail and allows for changes of those infos. 用户对象保存用户名或电子邮件等信息,并允许更改这些信息。 The login-status itself is stored in the session and also in a cookie. 登录状态本身存储在会话中,也存储在cookie中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM