首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Next-auth (JWT)日志记录会话

Next-auth (JWT)日志记录会话
EN

Stack Overflow用户
提问于 2022-04-23 13:04:31
回答 1查看 1.5K关注 0票数 0

根据Next文档,因为我们使用凭据提供程序连接到我们的用户集合以获取用户名和密码,所以Next-auth不使用会话数据库来检查会话是否处于活动状态。

如果使用自定义凭据提供程序,则NextAuth.js不会将用户帐户持久化到数据库中(即使配置了用户帐户)。必须启用使用自定义凭据提供程序的选项,为会话令牌使用JSON令牌(允许登录而不使用会话数据库)。

我想添加一个_middleware,它允许我存储和检查会话数据库中的最新JWT会话是否与用户当前使用的最新会话匹配。

原因是如果我在技术上有两个设备,我将能够在这两个设备上登录,而目前它们并不是识别来自PC2的用户是否也在PC1上登录的真正方法。

因此,我的理论和不确定这是否会起作用是添加以下内容。

代码语言:javascript
复制
callbacks: {
        jwt: async ({ token, user }) => {
          console.log("running JWT - because of custom login")
            user && (token.user = user)
            
            (ADD CODE HERE TO SAVE TOKEN & CHECK IF TOKEN IS LATEST TOKEN + VALID - INSIDE SESSION DATABASE)

            (IF OLD-TOKEN IS NO LONGER VALID OR THE LATEST TOKEN LOG THE USER OUT)

            console.log("TOKEN IS "+ JSON.stringify(token))
            return token
        },
        session: async ({ session, token, user }) => {
            console.log(JSON.stringify(session) +" / "+ JSON.stringify(token) +"/"+ JSON.stringify(user));

            
            session.user.tokenID = token //ADD CODE HERE TO SAVE TOKEN TO SESSION COOKIE

            session.user = user
            return session
        }
      },

然后,如果我创建一个中间件来检查这个tokenID并将它与会话数据库匹配,以及它是否是上述用户的最新结果。

例如。

假设PC1 (user1)在这里登录

代码语言:javascript
复制
{
_id: 1
tokenID: 918171-918171-81716-0887
userid: 00-00-00-001
expire: "2022-05-23T12:47:04.593Z"
}

但是PC2也(user1)再次登录并创建了一个新会话

代码语言:javascript
复制
{
_id: 2
tokenID: 71888-651777-616666-0117
userid: 00-00-00-001
expire: "2022-05-24T12:47:04.593Z"
}

我需要中间件(简单的mongodb查询可以这样做)检查它们是否是为同一个userID存储的旧会话,如果是,那么从PC1注销。

现在有几件事我可以看到这个想法出了问题。

其他提供程序会话(使用会话DB)使每次调用注册页或会话时验证

  • 变得更加困难,似乎重新运行JWT部分--理论上是可以的,因为我们可以使用findOne更新函数,如果令牌在会话中,则只更新到期时间--但是这会导致在PC2登录后PC1刷新时间比PC2过期时间长(但是一个简单的排序函数将允许我们查看ID是否较旧,如果每次重新加载page

时PC2会更改令牌)。

这将如何帮助隐私和用户数据?

  • 通过不将用户详细信息存储在会话cookie中,就不会将数据暴露给黑客或其他插件(如FB或Google ),因为用户数据只会链接到令牌ID。要请求用户数据,首先必须确保tokenID是有效的,然后才允许获取用户数据。

我明白,明年8月可能不想这样做,这就是为什么我问问题,什么是最好的做法,做我想要达到的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-23 14:01:54

此答案基于以下确认:问题在于您希望用户只能同时被登录到一台计算机/设备,并且您正在使用用户名和密码对它们进行身份验证。

在该场景中,还需要有一个数据库,该数据库在每个JWT发出的JWT中记录一个令牌。没有数据库是不可能解决这个问题的。

下面是如何使用JWT和数据库来解决这个问题:

在每个新登录的

  • 上,您都需要使用jwt回调将类似于UUID的内容添加到每个JWT中,然后记录UUID、用户ID以及JWT在数据库中过期的时间。如果数据库中有相同用户ID的其他条目,则应将它们标记为无效(或从database).
  • Everytime中删除它们-在相同的回调中读取现有的JWT ),您需要检查数据库中的UUID是否仍然有效(即仍然存在/没有指向对应于标记为过期的UUID的UUID),如果它不再有效,不要返回一个有效的jWT.
  • ,您可能还想在session回调中添加特殊处理,通过在他们被签出的计算机的用户界面中优雅地处理它,这样做可以改善用户体验。

实际上,这具有JWT的所有缺点和会话数据库的所有缺点(尽管在某些特定的情况下,这是一种更好的方法)。

我不建议使用用户名和密码,也不建议限制用户在同一时间只能登录到一台计算机上,但是,考虑到这些异常特殊的限制(这也需要一个对性能有负面影响的解决方案),您可能需要考虑另一种身份验证解决方案和/或考虑如何解决它试图解决的潜在需求(如果它值得的话)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71979882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档