Scala 剪影JWT令牌如何在无状态模式下保持有效?
我正在开发一个项目并使用身份验证框架。 对于来自浏览器UI的常规请求,我使用CookieAuthenticator,对于RESTAPI请求,我使用JWTAuthenticator。 下面是一部分带有文档的剪影源代码,它让我觉得我不完全理解这个东西是如何工作的:Scala 剪影JWT令牌如何在无状态模式下保持有效?,scala,playframework,silhouette,Scala,Playframework,Silhouette,我正在开发一个项目并使用身份验证框架。 对于来自浏览器UI的常规请求,我使用CookieAuthenticator,对于RESTAPI请求,我使用JWTAuthenticator。 下面是一部分带有文档的剪影源代码,它让我觉得我不完全理解这个东西是如何工作的: /** * The service that handles the JWT authenticator. * * If the authenticator DAO is deactivated then a stateless a
/**
* The service that handles the JWT authenticator.
*
* If the authenticator DAO is deactivated then a stateless approach will be used. But note
* that you will loose the possibility to invalidate a JWT.
*
* @param settings The authenticator settings.
* @param dao The DAO to store the authenticator. Set it to None to use a stateless approach.
* @param idGenerator The ID generator used to create the authenticator ID.
* @param clock The clock implementation.
* @param executionContext The execution context to handle the asynchronous operations.
*/
class JWTAuthenticatorService(
settings: JWTAuthenticatorSettings,
dao: Option[AuthenticatorDAO[JWTAuthenticator]],
idGenerator: IDGenerator,
clock: Clock)(implicit val executionContext: ExecutionContext)
extends AuthenticatorService[JWTAuthenticator]
with Logger {
注意文档的这一部分
如果已停用验证器DAO,则将使用无状态方法
被使用。但请注意,您将失去无效的可能性
JWT
因此,它的工作原理正是他们所说的。当我将
None
作为dao
参数的值传递时,生成的令牌保持有效,即使我关闭了应用程序。但如果没有支持存储,这些代币如何保持有效?当我再次启动应用程序并使用相同的令牌时,它会对用户进行身份验证。我不知道它是怎么做到的。你能解释一下吗?很简单。使用已知的salt和算法组合对令牌的内容进行编码。JWT令牌具有已知的结构,使用HMAC或RSA编码。服务器可以以无状态方式解密令牌,只要它们知道编码密钥(HMAC的密钥)和RSA的密钥对(例如)
如果你想变得聪明,你甚至可以自己做,看看里面的东西。JWT是标准化的,根据惯例,账户通常在iss
字段下可用。例如,在谷歌云中,iss
是你的谷歌服务帐户电子邮件,因此他们可以知道你是谁
进一步探索,您可以创建自己的会话
对象并将其编码为令牌
case class Session(user: UUID, timestamp: String, email: String)
// This is roughly the process used.
object TokenEncoder {
val secret = Play.current.configuration.getString("encryption.key")
def encode(session: Session): String = {
// The below line is just to make a point.
AES.encrypt(Json.toJson(session), someSharedKey)
}
def decode(str: String): Option[Session] = {
Json.parse(AES.decrypt(str, someSharedKey)).asOpt[Session]
}
}
在跨服务器请求的情况下,该令牌的字符串值可以在cookie或标头中使用,并且每台服务器都可以无状态地验证令牌并提取用户信息,只要他们知道用于执行编码的密钥
someSharedKey
。使用已知的salt和算法组合对令牌的内容进行编码。JWT令牌具有已知的结构,使用HMAC或RSA编码。服务器可以以无状态的方式解密令牌,只要它们知道编码密钥(HMAC的秘钥)和RSA的密钥对。是的,如果我想得更仔细一点,我会猜显然令牌本身应该嵌入有关链接帐户的信息。不过,服务器可以轻松解密令牌这一事实对我来说并不简单。你能把你的评论作为回答吗?这样我就可以接受了?