9

在创建 Web 应用程序时,假设您有一个表示单个用户的 User 对象,您认为存储用户已登录的最佳方式是什么?

我想到的两种方法是:

  • 将用户数据库 ID 存储在会话变量中
  • 将整个用户对象存储在会话变量中

有什么更好的建议,使用上述方法有什么问题吗?也许是安全问题或内存问题等。

4

8 回答 8

12

我建议存储 id 而不是对象。缺点是每次想要获取该用户的信息时都必须访问数据库。但是,除非页面中的每一毫秒都很重要,否则性能应该不是问题。这里有两个优点:

  1. 如果用户的信息发生了某种变化,那么您将不会在会话中存储过时的信息。例如,如果管理员授予用户额外权限,则这些权限将立即可用,而无需用户注销然后重新登录。

  2. 如果你的会话信息存储在硬盘上,那么你只能存储可序列化的数据。因此,如果您的 User 对象曾经包含数据库连接、打开的套接字、文件描述符等任何内容,那么这些内容将无法正确存储,也可能无法正确清理。

在大多数情况下,这些问题不会成为问题,任何一种方法都可以。

于 2008-08-21T20:09:47.333 回答
6

为安全起见,我将生成(GUID 或加密安全的 RNG)一个会话 ID,并有一个表将会话 ID 映射到用户 ID。然后,您只需将会话 ID 存储在他们的 cookie 中,并让它充当用户 ID 的代理。

|Session |UserID |
|--------+-------|
|a1d4e...+ 12345 |
|--------+-------|
|c64b2...+ 23456 |
|--------+-------|

有了这个,没有人可以通过猜测他们的 ID 来冒充另一个用户。它还允许您限制用户的会话,因此他们必须每隔一段时间登录一次(通常是两周)。如果您想存储有关他们会话的其他数据,您可以将其添加到此表中。

于 2008-08-21T22:27:13.977 回答
3

请记住,如果您将所有用户的属性(这延伸到权限)存储在会话中,那么对用户的任何更改都不会生效,直到他们再次登录。

就个人而言,我存储名称和 ID 以供快速参考,并在需要时获取其余部分。

于 2008-08-21T20:01:36.107 回答
2

在大多数情况下,存储 ID 是最佳做法。一个重要的原因是可扩展性。如果您存储用户对象(或数据库中的任何实体,而不仅仅是他们的 ID),您将遇到扩展为您的站点服务的服务器数量的问题。有关更多信息,请在 google 上搜索“无共享架构”。

于 2008-08-21T20:03:55.867 回答
1

我认为这取决于您使用的平台。如果您使用的是 ASP.net,那么我肯定会看看FormsAuthentication类和所有可用于存储登录用户设置的内置(和可扩展)功能。

于 2008-08-21T20:03:42.933 回答
1

我将存储用户 ID 和会话 ID 的散列值,然后将其匹配到数据库中的会话表中。这样就很难欺骗会话数据。我也可以检查 IP 作为额外检查吗?

不确定我是否希望依赖存储在会话变量中的用户 ID 并相信它是该用户,因为它可以很容易地更改并作为另一个成员获得访问权限

于 2009-03-10T10:20:32.490 回答
0

我通常将用户存储在会话中。无法更改直到登录问题可以通过在您进行更改后用新副本替换会话中的对象来解决。

于 2008-08-21T20:03:57.223 回答
0

我们的用户对象相当轻量,因此我们选择将其存储在会话变量中。不确定这是否是最有效的,但到目前为止它工作得非常好。

于 2008-08-21T20:04:24.757 回答