Database 惯用的处理方式是什么;短暂的;数据库中的状态?

Database 惯用的处理方式是什么;短暂的;数据库中的状态?,database,mongodb,design-patterns,state,Database,Mongodb,Design Patterns,State,我知道StackOverflow社区不赞成“最佳实践”类型的问题,但我不知道如何用别的词来表达 我的“大局”问题是: 在无状态服务器(比如提供RESTAPI的服务器)中处理“会话”状态时,什么是一个好的实践 快速详细信息 后端使用nodeJS,数据库使用MongoDB 示例1:登录状态 在管理面板的版本1中,我有一个简单的登录,要求输入电子邮件和密码。如果凭据正确,则向用户返回令牌,否则返回错误 在版本2中,我为激活它的用户添加了双因素身份验证。 为了保持简单,我现在有两个端点。流程如下: /

我知道StackOverflow社区不赞成“最佳实践”类型的问题,但我不知道如何用别的词来表达

我的“大局”问题是: 在无状态服务器(比如提供RESTAPI的服务器)中处理“会话”状态时,什么是一个好的实践

快速详细信息 后端使用nodeJS,数据库使用MongoDB

示例1:登录状态 在管理面板的版本1中,我有一个简单的登录,要求输入电子邮件和密码。如果凭据正确,则向用户返回令牌,否则返回错误

在版本2中,我为激活它的用户添加了双因素身份验证。 为了保持简单,我现在有两个端点。流程如下:

  • /管理员/验证密码:
  • /管理员/验证人:
verifytotpoken
步骤中,它需要知道管理员是否已经验证了密码。为此,我决定在名为
hasvirifiedpassword
的管理文档中附加一个“临时”字段,该字段在
verifyPassword
步骤中设置为true

不仅如此,我还在
verifyPassword
端点中设置了一个
passwordVerificationExpirationDate
临时字段,这样他们就有了一个短窗口,必须在该窗口内完成整个登录过程

我的方法的问题在于:

  • 它使用与管理员本身无关的短暂、临时状态来扩充管理员文档。在我看来,资源和会话是两个不同的东西
  • 它让陈旧数据保持活动状态并附加到
    admin
    文档,在数据库资源管理器中查看
    admin
    集合时,这充其量只是一个轻微的麻烦,最坏的情况下,由于垃圾数据未正确清理,可能导致难以检测的错误
示例2:2FA通过电子邮件进行激活确认 当管理员决定激活2fa时,出于安全目的,我首先向他们发送一封电子邮件,确认真正想要激活2fa的是他们(而不是劫持他们会话的人)。为此,我需要以某种方式传入散列并将其存储在数据库中

我目前的做法是:

1) 我在服务器端生成一个散列,并将其存储在他们的
admin
文档中以及过期日期

2) 我生成一个url,其中包含哈希作为查询参数,并将其发送到电子邮件中

3) 管理员点击电子邮件

4) 前端代码从查询参数中提取哈希值,并要求服务器对其进行验证

5) 服务器查找
admin
文档并检查哈希匹配。如果是的话,那太好了。返回
ok
并清除数据。如果不是,则返回一个错误。如果过期,请清理数据

在这里,我还必须使用一些临时状态(两个字段
hash
expirationDate
)。对于上述同样的问题,它也是脆弱的

我的要点 通过这两个例子,我试图说明我所面临的问题。虽然这些解决方案工作得“很好”,但我很好奇更好的程序员对我的方法有何看法,以及是否有更好、更惯用的方法来实现这一点


请记住,我的问题的目的不是为我的具体问题找到一个具体的解决方案。我正在寻找有关以一种巧妙、可维护的方式存储会话数据的更普遍问题的建议,这种方式不会混合资源状态和临时状态。

我看到两种方法:1。不要将此短暂状态存储在管理文档中。将它们存储在其他地方,存储在包含管理文档ID的单独文档中。2.使用JWT并将信息存储在令牌本身中。JWT是经过签名的,因此不能被篡改。因为第二种方法对于登录示例来说太具体了,所以我不会深入讨论。第一种方法似乎对一般问题更为合理。您会为每种类型的“状态”推荐一个集合吗?像2fa激活确认电子邮件的
2fa激活
,检查整个登录过程的
authSession
等?或者
sessionState
收集服务器端举行的任何类型的会话,可能还有一个类似
类型的判别字段:“auth”|“2faActivation”|……
?我从不使用文档数据库。你比我更有能力回答那个问题。
Receive email and password;
if(Credentials are correct) {
  if(Admin requires 2fa) {
    return {nextStep: 2fa};
  } else {
    return tokenCode;
  }
} else {
  return error;
}
Receive email and TOTP token;
Get admin with corresponding email
if(Admin has verified password) {
  return tokenCode
} else {
  return error;
}