根据Next文档,因为我们使用凭据提供程序连接到我们的用户集合以获取用户名和密码,所以Next-auth不使用会话数据库来检查会话是否处于活动状态。
如果使用自定义凭据提供程序,则NextAuth.js不会将用户帐户持久化到数据库中(即使配置了用户帐户)。必须启用使用自定义凭据提供程序的选项,为会话令牌使用JSON令牌(允许登录而不使用会话数据库)。
我想添加一个_middleware,它允许我存储和检查会话数据库中的最新JWT会话是否与用户当前使用的最新会话匹配。
原因是如果我在技术上有两个设备,我将能够在这两个设备上登录,而目前它们并不是识别来自PC2的用户是否也在PC1上登录的真正方法。
因此,我的理论和不确定这是否会起作用是添加以下内容。
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)在这里登录
{
_id: 1
tokenID: 918171-918171-81716-0887
userid: 00-00-00-001
expire: "2022-05-23T12:47:04.593Z"
}但是PC2也(user1)再次登录并创建了一个新会话
{
_id: 2
tokenID: 71888-651777-616666-0117
userid: 00-00-00-001
expire: "2022-05-24T12:47:04.593Z"
}我需要中间件(简单的mongodb查询可以这样做)检查它们是否是为同一个userID存储的旧会话,如果是,那么从PC1注销。
现在有几件事我可以看到这个想法出了问题。
其他提供程序会话(使用会话DB)使每次调用注册页或会话时验证
时PC2会更改令牌)。
这将如何帮助隐私和用户数据?
我明白,明年8月可能不想这样做,这就是为什么我问问题,什么是最好的做法,做我想要达到的。
发布于 2022-04-23 14:01:54
此答案基于以下确认:问题在于您希望用户只能同时被登录到一台计算机/设备,并且您正在使用用户名和密码对它们进行身份验证。
在该场景中,还需要有一个数据库,该数据库在每个JWT发出的JWT中记录一个令牌。没有数据库是不可能解决这个问题的。
下面是如何使用JWT和数据库来解决这个问题:
在每个新登录的
jwt回调将类似于UUID的内容添加到每个JWT中,然后记录UUID、用户ID以及JWT在数据库中过期的时间。如果数据库中有相同用户ID的其他条目,则应将它们标记为无效(或从database).session回调中添加特殊处理,通过在他们被签出的计算机的用户界面中优雅地处理它,这样做可以改善用户体验。实际上,这具有JWT的所有缺点和会话数据库的所有缺点(尽管在某些特定的情况下,这是一种更好的方法)。
我不建议使用用户名和密码,也不建议限制用户在同一时间只能登录到一台计算机上,但是,考虑到这些异常特殊的限制(这也需要一个对性能有负面影响的解决方案),您可能需要考虑另一种身份验证解决方案和/或考虑如何解决它试图解决的潜在需求(如果它值得的话)。
https://stackoverflow.com/questions/71979882
复制相似问题