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

Session Redis作为会话存储,使用户的所有会话无效,session,redis,reset-password,Session,Redis,Reset Password,我将redis用作会话存储 像这样存储会话 [NameSpace]:[UniqueId] -> [email_id] [NameSpace]:[UniqueId]-[email_id] -> [email_id] 问题是, 当用户重置密码时,如何使该用户的所有会话无效 以下是我提出的解决方案 将电子邮件id存储为UID的一部分 像这样存储会话 [NameSpace]:[UniqueId] -> [email_id] [NameSpace]:[UniqueId]-[emai

我将redis用作会话存储

像这样存储会话

[NameSpace]:[UniqueId] -> [email_id]
[NameSpace]:[UniqueId]-[email_id] -> [email_id]
问题是, 当用户重置密码时,如何使该用户的所有会话无效

以下是我提出的解决方案

将电子邮件id存储为UID的一部分 像这样存储会话

[NameSpace]:[UniqueId] -> [email_id]
[NameSpace]:[UniqueId]-[email_id] -> [email_id]
然后,当用户重置密码时,我可以使用
SCAN MATCH
删除所有密钥

维护UID列表 存储会话后,如

[NameSpace]:[UniqueId] -> [email_id]
保留一份单独的清单

[NameSpace2]:[email_id] -> [ "[UniqueId]", "[UniqueId]" ]
并使用列表使会话无效。(我可以使用
redis
namespace pubsub来维护上述列表的有效性)

我的问题是
  • 在redis中执行批量会话失效的推荐方法是什么
  • 在cookie中存储会话id如
    [UniqueId]-[email\u id]
    是否存在任何安全问题 PS:我知道有一个类似的问题,但我觉得这个问题很吵,而且是针对express.js的,而不是针对redis和用户会话的。
    ()

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


    Re。2-如果有人进入你的应用程序/db服务器,会有很多安全问题:)

    维护一组所有用户会话

    [NameSpace]:[email\u id]->{}

    每个会话标识符都是集合中的一个值。如果要存储会话属性,请使用映射
    sessionIdentifier1->sessionProperties1
    (查找和删除成本相同)

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

    批量会话无效-密钥
    [名称空间]:[email\u id]
    。成本O(1)

    查找sessionIdentifier-
    sessionIdentifier 1
    项的
    [名称空间]:[email\u id]
    。成本O(1)

    像这样存储会话id是否存在任何安全问题 cookie中的[UniqueId]-[email_id]吗


    视情况而定。如果cookie不是
    HttpOnly
    ,它将允许恶意JS通过XSS漏洞读取cookie。你可能会让自己受到网络钓鱼攻击。您可以使用用户的内部
    UUID

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

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

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

  • 使用哈希、排序集和计划任务进行清理。在这个方法中,您使用会话ID作为散列的键,该散列包含会话键及其值。其中两个成员是创建和最后一次看到的时间戳。然后,您可以为每个用户使用另一个哈希,该哈希将sessionid映射到最后看到的时间戳。使用此选项,您可以从选项1中保持页面刷新时的更新,但每个用户都有一个易于获取的会话列表。但是,这不会删除旧会话。您可以使散列过期,但您必须在页面视图上同时过期和更新这两个散列,或者为我们安排一个计划任务

  • 为此,您可以使用一个排序集,其中会话ID作为成员,时间戳作为分数。现在,您可以使用标准的排序集查询(如zrangebyscore)将早于某个时间戳的所有会话放入列表中,然后删除这些键和成员

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


    我建议每个用户使用一次会话,并自由使用expiration

    还有更多细节:谢谢你的回答,我将在这里与我的团队讨论。关于你的第二个答案,如果有人进入了app/db服务器,他们无论如何都可以读取密钥和值。所以我想这不应该是个问题。