下一个作者(JWT)记录会议
根据Next-auth文档,由于我们使用凭据提供商将用户名和密码连接到我们的用户收集Next-auth不会使用会话数据库来检查会话是否处于活动状态。
如果您使用自定义凭据提供商用户帐户不会在NextAuth.js的数据库中持续存在(即使已配置了一个)。必须使用JSON Web代币进行会话令牌的选项(允许在不使用会话数据库的情况下登录)必须使用自定义凭据提供商。
我想添加一个_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
}
},
然后,如果我创建了一个中间件,该中间件检查了这个令牌并将其与会话数据库匹配,并且是否是该用户的最新结果。
例如。
在此处说PC1(用户1)登录,
{
_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"
}
但 如果是这样,则可以从PC1注销。
现在,我可以看到这个想法出了一些问题。
- 其他提供商会话(使用会话db)使
- 每次调用注册页面或会话时都更难验证JWT部分 - 从理论上讲,这是可以的,因为我们可以使用findOne更新功能在会话中,然后只需更新到期 - 但是,这会导致PC1登录后PC1刷新,然后PC1过期可能会更长,然后PC2到期时间(但是一个简单的排序功能使我们能够查看ID是否年龄较大,pc2 the PC2如果是PC2,则所以注销)。
- JWT每次重新加载页面时都会更改令牌
这将如何帮助隐私和用户数据?
- 通过不将用户详细信息存储在会话cookie中,我们将不会将数据暴露于黑客或其他插件(例如FB或Google),因为用户数据仅链接到令牌ID。要请求用户数据,您将必须确保以代币有效,然后允许获取用户数据。
我知道下一个实体可能也不想做这件事,这就是为什么我问一个问题的原因是,做我想实现的最佳实践是什么。
According to Next-auth documentation as we are using credentials provider to connect to our users collection for usernames and passwords Next-Auth does not use the session database to check if a session is active.
If you use a custom credentials provider user accounts will not be persisted in a database by NextAuth.js (even if one is configured). The option to use JSON Web Tokens for session tokens (which allow sign in without using a session database) must be enabled to use a custom credentials provider.
I am wanting to add a _middleware that will allow me to store and check that the latest JWT sessions inside our session database matches the latest one that the user is currently using.
Reason being is that if I have two devices technically I would be able to login on both devices and at the moment their is no real way to discern if the user from PC2 is also login on PC1.
So my theory and not sure if this will work is to add the following.
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
}
},
Then if I create a middleware that checks this tokenID and matches it with the session database and if it is the latest result from said user.
For example.
Say PC1 (user1) login here
{
_id: 1
tokenID: 918171-918171-81716-0887
userid: 00-00-00-001
expire: "2022-05-23T12:47:04.593Z"
}
But then PC2 also (user1) login again and created a new session
{
_id: 2
tokenID: 71888-651777-616666-0117
userid: 00-00-00-001
expire: "2022-05-24T12:47:04.593Z"
}
What I would need the middleware to do (which a simple mongodb query could do) is check if their is an older session stored for the same userID if so then logout from PC1.
Now there are a few things that I can see going wrong with this idea.
- Other Provider Sessions (which use session DB) making it harder to validate
- Every time you call the signup page or session it seems to re-run the JWT section - which in theory is fine, as we could use a findOne Update function which if token is in session then just update the expiry - however that would cause say PC1 refreshes after PC2 logged in then PC1 expire time might be longer then PC2 expire time (but a simple sort function would allow us to see if the ID was older then PC2 if so logout).
- JWT changes token every time you reload the page
How would this help privacy and the user data?
- By not storing the user details inside a session cookie we would not be exposing the data to hackers or other plugins like FB or Google as the user data would only be linked to a token ID. Which to request the user data you would have to make sure the tokenID was valid first and then be allowed to fetch user data.
I understand that Next-Auth may not want too do this, and this is why I ask the question what is the best practice to do what I am wanting to achieve.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该答案基于这样的确认,即您希望只能在时间登录到一台计算机/设备,并且您使用用户名和密码来验证它们。
在这种情况下,您还需要拥有一个数据库,该数据库记录每个JWT中的令牌。没有数据库就无法解决该问题。
这是您可以使用JWT和数据库来解决它的方法:
jwt
呼叫来添加uuid之类的东西,然后记录UUID ,用户ID和JWT在数据库中到期的时间。session
回调中添加特殊处理,该回调可以通过在他们正在签名的计算机的用户界面中优雅地处理来改善用户体验。实际上,这具有JWT的所有缺点,并具有会话数据库的所有缺点(尽管在某些情况下,这是一种可取的方法)。
我不建议使用用户名和密码或限制用户只能在当时登录一台计算机,但是考虑到这些异常特定的约束(这也需要对性能产生负面影响的解决方案),您可能需要考虑一种不同的身份验证解决方案和/或认为您还能解决基本需求,这是试图解决的(如果是值得的成本和复杂性)。
This answer is based on the confirmation that the issue is that you want to be able to only have users able to be signed in to one computer/device at time and that you are using usernames and passwords to authenticate them.
In that scenario you also need to have a database that records a token in each JWT issued. It is not possible to solve for that problem without a database.
Here is how you can solve for it it using JWT and a database:
jwt
callback to add something like a UUID to each JWT and then record that UUID , the User ID and the time the JWT expires in a database.session
callback that does something similar to improve the user experience by gracefully handling it in the User Interface of the computer they are being signed out of.Effectively this has all the downsides of a JWT with all the downsides of a session database (although there are niche cases where this is a preferable approach).
I would not recommend using usernames and passwords or limiting users to only being able to sign in to one computer at at time, however given those unusually specific constraints (which also necessitates a solution that has a negative impact on performance) you may want to consider a different authentication solution and/or think how else you could address the underlying need this is trying to address (and if it's worth the cost and complexity).