spring 将 JWT 存储在数据库中有意义吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42763146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does it make sense to store JWT in a database?
提问by laurentius
I've implemented a basic authentication system with Spring Boot, Spring Security, OAUTH2 and JWT as auth tokens. It works alright but I was thinking if it makes sense to store JWT in a database and check if a token exists every time someone makes an authenticated request using it? I was thinking specifically of the following scenario: user is authenticated in a mobile device and they lose it so they want to deauthorize that device. They would then be able to issue an operation that clears the tokens issued to their user id and deauthorize all tokens assigned to him. Any other way? Am I thinking this wrong or overcomplicating things?
我已经使用 Spring Boot、Spring Security、OAUTH2 和 JWT 作为身份验证令牌实现了一个基本身份验证系统。它工作正常,但我在想将 JWT 存储在数据库中并在每次有人使用它进行身份验证请求时检查令牌是否存在是否有意义?我特别考虑了以下场景:用户在移动设备中进行了身份验证,但他们丢失了它,因此他们想取消对该设备的授权。然后,他们将能够发出一个操作,清除发给他们的用户 ID 的令牌并取消分配给他的所有令牌的授权。还有什么办法吗?我认为这是错误的还是过于复杂的事情?
This is for securing a REST API that is going to get called from a mobile APP.
这是为了保护将从移动应用程序调用的 REST API。
回答by sdoxsee
You could store the JWT in the db but you lose some of the benefits of a JWT. The JWT gives you the advantage of not needing to check the token in a db every time since you can just use cryptography to verify that the token is legitimate. If you have to look up the token in the db, you might as well just use an opaque token that doesn't carry information with it and let the server and database provide you with the information. On the other hand, if you're going to store a token in the db, I don't think a JWT is a bad choice for your token type. As you say, there are advantages for revocation if you store your token in the db. It all depends on what you want to achieve (faster authorization, etc. vs ability to revoke on demand).
您可以将 JWT 存储在数据库中,但会失去 JWT 的一些好处。JWT 为您提供了无需每次都检查数据库中的令牌的优势,因为您只需使用加密技术来验证令牌是否合法。如果您必须在数据库中查找令牌,您不妨使用一个不带有信息的不透明令牌,让服务器和数据库为您提供信息。另一方面,如果您打算在数据库中存储令牌,我认为 JWT 不是您的令牌类型的错误选择。正如您所说,如果您将令牌存储在 db 中,则撤销具有优势。这完全取决于您想要实现的目标(更快的授权等与按需撤销的能力)。
You can still use JWT with OAuth2 without storing tokens in the db if you want. JWTs have a configurable expiry time that you can set--after which they are invalid. Access Tokens (whether JWT or not) should usually be short-lived for security. If the concern is someone's phone being stolen and access tokens being obtained, I think the solution is to have those tokens expire quickly (30 mins?). If you're using oauth2, the means of stopping someone from continuing to use the app is for the real owner to de-authorize the mobile app client on the authorization server so that no more access tokens will be given out.
如果需要,您仍然可以将 JWT 与 OAuth2 一起使用,而无需在数据库中存储令牌。JWT 有一个可配置的到期时间,您可以设置它——在此之后它们将无效。为了安全起见,访问令牌(无论是否为 JWT)通常应该是短暂的。如果担心某人的电话被盗并获得访问令牌,我认为解决方案是让这些令牌快速过期(30 分钟?)。如果您使用的是 oauth2,阻止某人继续使用该应用程序的方法是让真正的所有者在授权服务器上取消对移动应用程序客户端的授权,这样就不会再发出访问令牌。
回答by Jan Pavtel
You can set expiration date (for mobile 1 week).
Add some custom field refreshIdfor user (you can use uuid for this).
Next set Issued at claims parameter ("iat").
Store refreshIdinto db and set it as claims parameter .
Then every time when you validate token you should check the token's "age". If it older than one hour you should load data from DB and check refreshIdvalue and create new token with current "iat" value and send it to mobile device. When you need to deactivate tokens just generate new value for refreshIdin db. After one hour all tokens will be incorrect, so user will need to login on every device again. You can make more custom solution if you need to.
您可以设置到期日期(手机 1 周)。refreshId为用户添加一些自定义字段(您可以为此使用 uuid)。下一组在声明参数(“iat”)处发布。存储refreshId到 db 并将其设置为 claim 参数。然后每次验证令牌时,您都应该检查令牌的“年龄”。如果超过一小时,您应该从数据库加载数据并检查refreshId值并使用当前“iat”值创建新令牌并将其发送到移动设备。当您需要停用令牌时,只需refreshId在 db 中生成新值。一小时后,所有令牌都将不正确,因此用户需要再次登录每台设备。如果需要,您可以制作更多自定义解决方案。

