2015-02-06 75 views
2

我使用的Redis作为会话存储,的Redis作为会话存储,无效的用户的所有会话

存储会话像这样

[NameSpace]:[UniqueId] -> [email_id] 

这是问题所在,

时用户重置密码,我如何使该用户的所有会话无效?

这里是解决方案我想出了,

存储电子邮件ID为

存储会话像这样

[NameSpace]:[UniqueId]-[email_id] -> [email_id] 

UID的一部分,那么我可以用SCAN MATCH删除所有当用户重置密码时使用密钥。

维护的UID

的列表存储会话后像

[NameSpace]:[UniqueId] -> [email_id] 

保持与

[NameSpace2]:[email_id] -> [ "[UniqueId]", "[UniqueId]" ] 

一个单独的列表,并使用无效列表中的会话。 (我可以用redis命名空间发布订阅来维持上述名单的有效性)

我的问题是

  1. 什么是推荐的方式做批量会话无效在Redis的?
  2. 在cookie中存储像[UniqueId]-[email_id]这样的会话标识是否存在安全问题?

PS:我知道有类似的问题,但我觉得它很嘈杂,面向express.js,而不是通用的redis和用户会话。 (Invalidating all of a single user's sessions in express.js

回答

1

Re。 1 - 因为活动用户会话的数量远远低于(大概)数据库中的会话总数,所以我会去手动管理每个用户的活动会话而不是SCAN ning。但是,我会使用每个用户的集合来存储活动会话密钥标识符而不是列表,因为您希望能够有效地添加和删除活动会话。如果用户有一个批次需要批量失效的活动会话,则可以使用SSCAN而不是SMEMBERS

Re。 2 - 如果有人钻进你的应用/数据库服务器有很多的安全问题:)

+0

此外还有一些更多细节在这里:https://groups.google.com/d/msg/redis-db/Vm7c4gvXgl8/vdRw-z1YuxgJ – 2015-02-06 15:49:57

+1

感谢您的答案,我会与我的团队在这里讨论。 关于你的第二个答案,如果有人进入app/db服务器,我们无论如何都完成了,他们无论如何都可以读取键和值。所以这不应该是我想的问题。 – Gautam 2015-02-06 15:59:39

1

维护一组的所有用户会话

[NameSpace]:[email_id] -> {}

每个会话标识符是集合的值。如果你想存储会话属性使用地图sessionIdentifier1 -> sessionProperties1(查找和删除成本是相同的)

[NameSpace]:[email_id] -> {sessionIdentifier1 , sessionIdentifier2}

散装会话失效 - Delete关键[NameSpace]:[email_id]。成本O(1)。

展望了sessionIdentifier - 关键[NameSpace]:[email_id]SISMEMBERsessionIdentifier1。成本O(1)。

在Cookie中存储会话ID像 [UniqueId] - [email_id]是否存在任何安全问题?

这取决于。如果cookie不是HttpOnly,它将允许恶意JS通过XSS漏洞读取该cookie。您可以开放自己的网络钓鱼攻击。您可以改用用户的内部UUID

1

根据您的示例,看起来您将会话存储为键 - >单个值对,并且用户可以有多个会话。有几种方法可以解决这个问题。

  1. 在页面加载时使用非常短的到期和刷新。作为密码更改代码的一部分,您从用户会话中提取会话ID并将其删除。短期到期确保删除旧会话。

  2. 使用散列或一组散列。根据用户数量,您可以使用单个散列,如果“小”用户群,或将它们散列到存储桶中。然后,您可以存储名称空间:会话[用户ID] - >电子邮件。此时您可以轻松删除单个用户会话,并且您没有重复的会话。您确实失去了自动过期会话的能力。

  3. 使用散列值,排序集和清理的计划任务。在此方法中,您使用会话ID作为具有会话密钥及其值的散列的密钥。其中两名成员是创作人,最后一次看到时间戳。然后,您可以为将sessionid映射到上次看到的时间戳的每个用户使用另一个散列。有了这个功能,您可以从选项1中更新页面上的更新,但您可以轻松获取每个用户的会话列表。但是,这不会修剪旧时段。您可以过期散列,但是您必须同时过期并更新页面视图或我们的计划任务。

为此,您可以使用以会员ID作为成员和时间戳记作为分数的有序集合。现在,您可以使用标准的排序集查询(如zrangebyscore)将比特定时间戳更早的所有会话都列入列表,然后删除这些键和成员。

您可以通过让会话创建代码检查用户的会话散列是否存在并使用过期或让会话创建代码检查上次更新在活动会话条件中并重新使用它来阻止多个会话使用此选项或从中清除临时成员。因为您可以有单个会话,或者可以轻松地提取列表,并希望到期和/或计划任务可以删除旧会话,管理会话变得更加容易 - 而且无需扫描或密钥。

我建议每个用户使用单一会话并自由使用到期。