我们正在实现一个需要身份验证和授权的 REST 服务。由于 REST API 的无状态特性,我们希望使用 JWT 通过令牌对 API 进行经过身份验证的调用,而无需为每个 API 调用访问数据库。
在评估了 JWT 之后,我们有一些问题:
- 您如何处理客户端和服务器之间共享的令牌机密泄露的情况?
- 您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)
- 有没有办法只注销受感染的客户端?
背景细节:我们将在 iOS 应用程序和 Node.js 后端之间使用该流程。
我们正在实现一个需要身份验证和授权的 REST 服务。由于 REST API 的无状态特性,我们希望使用 JWT 通过令牌对 API 进行经过身份验证的调用,而无需为每个 API 调用访问数据库。
在评估了 JWT 之后,我们有一些问题:
背景细节:我们将在 iOS 应用程序和 Node.js 后端之间使用该流程。
要回答您的问题:
1)您如何处理客户端和服务器之间共享的令牌机密泄露的情况?
为您的令牌添加到期日期。确保令牌在过期时间后无法使用。但这并不能防止在令牌有效期内进行未经授权的访问。
因此,为了克服这个问题,您可以在令牌中嵌入客户端的 IP 地址或其他此类信息。并确保带有令牌的传入请求是从发出它的同一 IP 地址使用的。
2)您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)
如果您的意思是注销所有以授权方式使用多个令牌的客户端,那么不。您可以继续同时使用多个令牌,前提是您有一个有限的令牌到期期限。这确保您的令牌在预期的时间范围内使用。
但是,如果您的意思是令牌被盗并且您以某种方式弄清楚了。最好使该用户的所有令牌无效。
但是,您可能希望有一种机制可以在特殊情况下显式撤销所有令牌。可能就像用户重置他的密码,因为他认为他的密码可能被泄露。
3) 有没有办法只注销受感染的客户端?
可能是,取决于您准确识别哪个令牌已被泄露的能力。这可能会导致所有使用该令牌的客户端失去访问权限。但是,我不会推荐它。但是,嘿,您总是可以编写代码,当旧客户端不能再使用令牌时,动态重新验证并获取新的访问令牌。:-)
必要时不要害怕使令牌无效。如果您丢失了令牌,请编写动态脚本以重新进行身份验证。如果您认为在使用新令牌时可能会丢失会话详细信息,请在重新验证时将过期的令牌重新发送到服务器。使用此过期令牌,您可以使用旧令牌的会话详细信息重建新令牌。前提是您在过期令牌中嵌入了会话详细信息。
如果您希望能够在其到期日期之前撤销之前授予的令牌(一个有效的安全问题),您需要包含一个数据库查找,这否定了 JWT 的主要优势之一,所以您可能决定不首先使用它们。
这是一篇关于这个案例的文章:https ://www.dinochiesa.net/?p=1388
JWT 令牌可以解码,所有信息都可以读取为 json 格式,例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
第一部分是标题: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{
"alg": "HS256",
"typ": "JWT"
}
第二部分是有效载荷: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
最后一部分是创建为的签名:
//In our example, the algorithm is (HS256)
signature = algorithm(hash of (header + payload), secret)
现在,它只是隐藏在令牌签名中的密钥,那么,我们得出结论:
signature
密钥验证,不得信任 JWT 令牌。阿卡哈斯
1)您如何处理客户端和服务器之间共享的令牌机密泄露的情况?
使用 SSL/TLS(安全连接)并根据您的登录系统使每个令牌过期。每次用户登录创建 JWT 令牌时,JWT 令牌必须用作永久令牌。
2)您是否注销所有客户端并为将来的请求定义新的令牌密码?(那将是一个糟糕的体验)
如果您的密钥被泄露,您必须创建新的密钥并通过发出注销更新活动会话并强制系统重新验证所有活动用户。