JSON Web Tokens 是一种标准化的对象,用于安全地在两个方之间发送数据。为了确保 JWT 的内容在传输过程中没有被篡改或篡改,JWT 使用加密密钥进行签名。需要重复的是: JWTs 被签名,而不是加密。签名验证数据的发送者,而加密将数据从明文转换为无法被未经授权的接收者读取的密文。如果签名令牌内容在传输过程中被更改,公钥(用于签署令牌的私钥的配对)将无法再验证签名。
Token 结构
这是一个最简单的 JWT Token
:
JSON Web Token 有三部分组成
- Header - 标题
- Payload - 有效载荷
- Signature - 签名
Header
和 Payload
都是 Base64Url 编码的,为了签署令牌,编码的头部和编码的有效负载与密钥和签名算法一起用于完成签名,这三者之间分别使用 .
号链接
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
上面的 Token 经过解析之后是下面这样子:
Header
typ
: 令牌类型alg
: 签名算法
Payload
有效载荷是包含所有实际信息的部分
- “iss” = 发行者声明。发行者声明标识了发出 JWT 的主体
- “sub” = 主题声明。主题声明标识了 JWT 的主体。
- “aud” = 受众声明。受众声明标识了 JWT 的预期接收者
- “exp” = 过期时间声明。过期声明标识了 JWT 在此时间之后必须不被接受进行处理。
- “nbf” = 不早于声明。NFB 声明标识了 JWT 在此之前不得被接受进行处理。
- “iat” = 发行时声明。发行时声明标识了 JWT 发行的时间
- “jti” = JWT ID 声明。JWT ID 声明为 JWT 提供了唯一标识符
Signature
Header 和 Payload 都是 Base64Url 编码的,与密钥和签名算法一起用于完成签名
尺寸问题
一些复杂的应用程序需要在令牌中存储大量信息。当令牌存储在 cookie 中时,这可能会增加每个请求的开销,甚至超过 cookie 的允许大小(4 KB)。当发生这种情况时,一种常见的解决方法是将 JWT 存储在<强>本地存储中,这会带来自己的安全问题,主要是本地存储中的数据可以被页面内的任何脚本访问。这可能导致跨站脚本(XSS)攻击能够访问令牌。
为什么建议将 Token
存储在 Cookie
中?
一般来说,cookie 是由服务器读取的,而本地存储只能由浏览器读取。这意味着 cookie 受到的数据量限制比本地存储要小。当令牌存储在本地存储中时,浏览器使用 JavaScript 来访问它。这就是为什么存储在本地存储中的令牌容易受到跨站脚本攻击的根本原因,因为攻击者可以将恶意 JavaScript 注入到网页中并窃取访问令牌。本地存储不提供像 cookie 中的安全属性那样的安全措施。不要误会,如果令牌存储在未经适当保护的 cookie 中,我们也容易受到 XSS 攻击。但是 cookie 有机制来保护令牌免受这类攻击,这也是为什么 OWASP 社区建议使用 cookie 存储令牌。
令牌失效
令牌是自包含的。没有中央机构来跟踪和管理令牌。当尝试使令牌无效时,这就成为一个挑战。默认情况下,访问令牌的生命周期为一(1)小时,到期的详细信息包含在令牌中。
Token 未加密
令牌是有签名的,但不是加密的。因此,如果没有足够的 HTTPS 保护,令牌内容可能会暴露给未经授权的第三方。
资料: