我使用redis作为会话商店,
存储类似的会话
[NameSpace]:[UniqueId] -> [email_id]
当用户重置密码时,如何使该用户的所有会话无效?
以下是我提出的解决方案,
像这样存储会话
[NameSpace]:[UniqueId]-[email_id] -> [email_id]
然后,当用户重置密码时,我可以使用SCAN MATCH
删除所有密钥。
存储会话后,如
[NameSpace]:[UniqueId] -> [email_id]
使用
维护单独的列表[NameSpace2]:[email_id] -> [ "[UniqueId]", "[UniqueId]" ]
并使用列表使会话无效。 (我可以使用redis
命名空间pubsub来维护上面列表的有效性)
[UniqueId]-[email_id]
)是否存在安全问题? 答案 0 :(得分:1)
重新。 1 - 由于活动用户会话的数量远远低于(可能)数据库中会话总数的数量,因此我需要手动管理每个用户的活动会话而不是SCAN
ning。但是,我会使用每个用户设置来存储活动会话密钥标识符而不是列表,因为您希望能够有效地添加和删除活动会话。如果用户的批次活动会话需要批量生效,则可以使用SSCAN
代替SMEMBERS
。
重新。 2 - 如果有人进入您的app / db服务器,则存在很多安全问题:)
答案 1 :(得分:1)
维护一组所有用户会话
[NameSpace]:[email_id] -> {}
每个会话标识符都是集合中的值。如果您想存储会话属性,请使用地图sessionIdentifier1 -> sessionProperties1
(查找和删除费用相同)
[NameSpace]:[email_id] -> {sessionIdentifier1 , sessionIdentifier2}
批量会话失效 - Delete密钥[NameSpace]:[email_id]
。费用O(1)。
查找密钥sessionIdentifier1
的sessionIdentifier - SISMEMBER [NameSpace]:[email_id]
。费用O(1)。
存储session-id是否存在任何安全问题 [UniqueId] - Cookie中的[email_id]?
这取决于。如果cookie不是HttpOnly
,它将允许恶意JS通过XSS漏洞读取该cookie。您可能会对网络钓鱼攻击持开放态度。您可以改为使用用户的内部UUID
。
答案 2 :(得分:1)
根据您的示例,您似乎将会话存储为键 - >单值对,并且用户可以拥有多个会话。有几种方法可以解决这个问题。
使用非常短的过期时间并刷新页面加载。作为密码更改代码的一部分,您从用户的会话中提取会话ID并将其删除。短期到期可确保删除旧会话。
使用散列或散列集。根据用户数量,您可以使用单个哈希,如果是“小”用户群,也可以将它们哈希到桶中。然后,您可以存储名称空间:sessions [userid] - >电子邮件为您的会话。此时,您可以轻松删除单个用户会话,并且您没有重复的会话。您确实无法自动使会话过期。
使用散列,排序集和计划任务进行清理。在此方法中,您使用会话ID作为具有会话密钥及其值的散列的键。其中两个成员是创造和最后看到的时间戳。然后,您可以为将sessionid映射到上次查看时间戳的每个用户使用另一个哈希。通过此操作,您可以从选项1继续更新页面刷新,但是您可以轻松获得每个用户的会话列表。但是,这并不能修复旧会话。您可以使散列过期,但是您必须使两者都过期并在页面视图或我们的计划任务上更新。
为此,您可以使用以会话ID作为成员的排序集,并将时间戳作为分数。现在,您可以使用标准的有序集查询(例如zrangebyscore)将所有早于某个时间戳的会话放入列表中,然后删除这些键和成员。
您可以通过让会话创建代码检查用户的会话哈希是否存在并使用到期或让会话创建代码检查上次更新是否在您的活动会话条件中并重新使用它来阻止多个会话使用此选项明确瞬态成员。因为您要么只有一个会话,要么可以轻松提取列表,并希望有过期和/或计划任务来修剪旧的,管理会话变得更加容易 - 而且无需扫描或密钥。
我建议每个用户使用单个会话并自由使用到期日期。