【发布时间】:2013-01-19 04:39:42
【问题描述】:
首先,我没有找到任何类似的问题或有用的材料。如果我遗漏了什么,我很抱歉!
其次,我对像 node-passport 或 connect-auth 或 everyauth 这样的现成解决方案不感兴趣
现在回答问题。我正在使用 Redis 来存储快速会话。我的问题是,当用户进行身份验证时(即发布用户名和密码并在集合中找到此类用户后)我应该在会话中存储什么?
我可以存储整个用户对象(例如,它来自 MongoDB 的方式)。我看到的一个缺点是,当用户在数据库中被修改时(他编辑了他的个人资料),我必须在会话中“重新设置”用户对象。如果例如管理员更改了用户的配置文件,它会变得更加复杂 - 在这种情况下,会话不知道用户已被修改并且需要从数据库刷新其数据,因此会话当前持有过时的用户对象,这将仅在用户下次登录时更新。
-
创建一个“hash => userid”的集合并在会话中只存储哈希。然后每个请求,调用一个将检查的中间件(下面的伪代码,省略了对不存在哈希的检查,在这种情况下,用户可能会被视为会话过期后未登录):
if(req.session 中的用户哈希) res.local.user = db.users.findById(db.sessions.findUserIdByHash(req.session.userhash));
这种方法的明显缺点是额外的集合(即 mongodb)或 key => 值(即 redis)存储 hash => userid 这还需要一些程序来清理旧会话散列(计划任务\cron将运行并删除旧的过期哈希)。
另一个类似于 #2 的解决方案,不是使用 3-d 方集合/key=>值存储,而是将哈希作为部分用户对象存储在 MongoDB 中。然而,此方法消除了额外的集合/redis 键值,但仍需要计划任务来清理旧的过期会话。并且由于过期会话可能由“过期日期”属性定义,因此更容易维护活动会话的 3-d 方集合,而不是将会话相关数据放入 MongoDB 中的用户对象中(从而使用户对象变得巨大)。
我是 Node-js 的新手,这就是我问的原因。我也明白可能没有正确答案,或者可能受限于个人喜好。
谢谢!
【问题讨论】:
-
请教您几个问题... 1 您的应用中出现不一致的代价是什么? 2 你计划有多少用户,你有什么硬件资源? 3 使用模式是什么?即稀疏但密集的会话、零星的每日访问等。4 新鲜代码具有成本和风险,是什么让您想要使用自己的解决方案而不是更成熟的模块?
-
@Richard Marr 1 您所说的应用程序不一致是什么意思? 2 该项目处于早期开发阶段,关于用户我不能告诉你(越多越好),假设每天大约 1k,关于硬件 - 任何现代硬件,如 amazon/heroku/节点柔术。 3 我会说零星的每日访问。 4 a) 获得 nodejs 技能的能力 b) 我不需要 3d 派对模块提供的大部分功能,例如社交网络登录/ oauth c) 比使用 3d 派对模块更容易集成自己的解决方案
-
正如@josh3736 指出的那样,这实际上是一个会话应该做什么的问题,而不是特定于 Node.js 的问题。但是,根据您想学习的技能做出架构决策是一种不好的方法。学习现有模块可能看起来比编写自己的模块更难,但你编写的每一行代码都是你必须维护的。这是一种常见的反应(我自己也做过),但这是一个错误。我能提供的最好建议是使用成熟的模块。如果您在熟悉后觉得它们不好,请自己写,我很乐意看到。
-
@Richard Marr 谢谢!您对模块的评论更多。 Node.js 很年轻,它的模块更年轻,作为开发人员,对我来说,唯一比维护自己的代码更糟糕的事情就是维护别人的代码。一些模块是节点的事实上的标准,其他的提高和消失。无论如何,这个讨论不会结束,因为我的观点很坚定:) 无论如何谢谢!
-
可能现有的标准模块还不成熟,但它们的眼球和经验比您的代码要多得多。你所说的不动表明你的决策过程缺乏理性,所以在这一点上,我会让你犯错误。祝你好运。
标签: node.js session authentication