今天,JSON Web Tokens 广泛用于应用程序中以共享安全信息。尽管如此,它们并非完全万无一失,可能会为攻击者打开大门。
但是,如果我们正确使用 JWT,我们可以避免这些缺点。因此,在本文中,我将讨论使用 JSON Web Tokens 时需要遵循的 5 个最佳实践。
1. 选择最合适的算法
一个 JSON Web Token 由 3 部分组成,分别是 Header、Payload 和 Signature。标头包含有关令牌类型和签名算法的信息。
|
有多种类型的签名算法可用,每种算法都有独特的功能。
例如,像对称算法算法允许您签署使用共享密钥的消息,而所述非对称算法和使用公共和私有密钥对。
然而,RS256是最推荐使用的算法,因为,
- 它为各种语言和实现提供更广泛的支持。
- 只有私钥持有者可以对令牌进行签名,其他人可以使用公钥来验证其签名。
- 您可以使用 为各种受众请求有效令牌RS256。
- 如果您的私钥被盗,您可以使用RS256更新后的密钥进行密钥轮换,而无需重新部署。(但是使用HS256,您将不得不重新部署。)
2. 始终对令牌进行签名
选择适当的算法后,您必须始终在发送令牌之前对其进行签名。
JWT 签名是确保令牌中的数据(有效负载)未被更改的基本安全功能。
要创建 JWT 签名,您需要编码的标头、编码的有效负载、机密和标头中指定的算法。例如,带有HMACSHA256算法的签名如下所示:
|
因此,如果标头或有效负载有任何更改,您将必须创建一个新的令牌签名。
此外,您可以在声明中包含一个随机令牌 ID,jti以防止两个令牌同时具有完全相同的签名。
3. 使用基于时间的声明
为 JWT 令牌定义合适的生命周期至关重要,因为不可能使它们无效。例如,id 或访问令牌不能被撤销,因为它不与任何会话相关联。
因此,您应该将 JWT 的生命周期设置得尽可能短,最多以秒或分钟为单位。但永远不要设置在几天或几个月内。
您可以使用exp声明来设置过期时间,并且只有当当前日期/时间必须在过期时间之前时,令牌才会有效。
|
同样,还有 2 个基于时间的声明可用于 JWT:
- nbf声明 — 可以为此声明指定一个“不在之前”的时间段,如果当前时间早于声明中的时间nbf,则令牌将被拒绝。
- iat 声明——“发布于”声明定义了 JWT 的发布时间,它可用于拒绝太旧而无法与您的资源服务器一起使用或在已知事件之前发布的令牌。
4. 设置发行人和受众
在 JWT 中定义颁发者和接收者是另一个要遵循的好习惯。您可以为此使用iss和aud声明,这将使接收者的令牌管理变得更加容易。
通过这些声明,他们将检索签名密钥并检查它是否是为他们颁发的令牌。
|
例如,如果您是接收方,您必须在接受之前验证 JWT 是由相关方(iss )签发并为您签发(aud)。
这降低了攻击者通过利用为其他人指定的令牌来访问您的数据的机会。
5. 不要使用 JWT 作为会话令牌
乍一看,将 JWT 用于会话令牌似乎是一个明智的选择,因为 JWT 不涉及用于会话验证的数据库查找。但是,实际上,JWT 不是会话处理的好选择。
由于 JWT 的标准很复杂,用户往往会在令牌设置上犯错,从而允许攻击者克隆它们并假装成其他人。
此外,当用户从系统注销时,我们应该能够通过简单地从会话存储中删除会话令牌来使会话“无效”。但是,这对于 JWT 令牌是不可行的。我们无法删除令牌,因为它是独立的,并且没有集中控制来使其无效。
最后但并非最不重要的一点是,由于 JWT 很大,在 cookie 中使用它们会带来巨大的每个请求成本。因此,建议不要将它们用作会话令牌。
为您的 Web 应用程序使用身份提供程序时,请使用 JWT 来识别和验证用户。
然后,您可以通过使用经过验证的用户信息(不将 JWT 直接存储在 Cookie 中)建立会话来转换到 Cookie 身份验证。