浅析JWT
浅析jwt
基本用法,基本原理什么的,问问ai都知道了,这里只简略带过。主要是在后面记录些自己的总结和思考
JWT 组成
json web token,由三部分组成,用 .
分隔:
Header.Payload.Signature
1. Header(头部)
- 描述令牌类型和签名算法
- Base64Url 编码的 JSON
{
"alg": "HS256", // 签名算法(HS256/RSA等)
"typ": "JWT" // 令牌类型
}
2. Payload(负载)
-
携带实际数据(claims)
-
Base64Url 编码的 JSON
-
三种声明类型:
{ // 标准声明(建议但不强制) "iss": "auth-server", // 签发者 "exp": 1620000000, // 过期时间 "sub": "user123", // 主题 // 公共声明(可自定义) "name": "John Doe", // 私有声明(双方约定) "role": "admin" }
3. Signature(签名)
-
防篡改核心保障
-
计算公式:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret-key )
4. jwt 实例
以上是以明文形式展示的 jwt 组成,实际上服务器会将编码后的 header,payload 以及签名通过 ‘.’ 连接并发给客户端
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
jwt过期时间
jwt会在payload中设置过期时间,服务端接收到请求是会验证该jwt是否过期,过期则需要用户重新登录。
为什么?
- 出于安全性考虑,如果jwt被窃取,攻击者就可以无限期地使用它来访问用户的资源
- 控制会话时长,有些服务不能让用户长期保持登录状态
- 避免内存泄漏,服务器会存储用户令牌状态,无限期的令牌会导致内存爆了
令牌状态
实际中,服务器可能会为每个令牌存储令牌的状态
为什么?
答:从安全性考虑,当用户执行 “注销” 操作、账户被盗用或出现异常登录行为时,服务器可迅速将对应的令牌标记为无效。这样,即便攻击者获取到该令牌,也无法再利用它访问系统资源,有效降低了安全风险。
这不是与令牌的无状态特性相违背了吗?
答:确实会在一定程度上影响令牌的无状态性,但不能简单说完全失去了无状态性,准确的说是在 安全性和无状态性之间的权衡
分布式系统中还要考虑令牌信息的一致性,这又导致令牌失去了灵活性?
答:同上,是在安全性和灵活性之间的权衡
总结&注意:
jwt 相当于服务器给客户端颁发的一个 “身份证”
- 服务端不必存储用户的登录状态,而是在登录的时候给用户生成一个jwt,用户下次访问时带上jwt即可,是个服务器无状态的设计
- 这个身份证不可以被篡改,若被篡改,服务器能发现(服务器是唯一拥有密钥的)
- 这个身份证可能会泄露信息,因为它只防止篡改,但是header和payload部分能被解码,所以不适合在jwt中携带过多敏感信息
- jwt 本身也不适合携带多余的用户状态,因为每次客户端发出的请求都要携带完整的jwt,在jwt中存储过多信息,会造成传输延迟。如果有较多的状态信息,还是结合session机制实现较好。jwt只用于身份验证即可。
个人感悟
cookie和session代表两种会话状态存储机制,cookie存在客户端本地,session存在服务器。
由于cookie的设计存在安全隐患,慢慢的cookie受到了跨域限制
而session会增加服务器的存储负担
jwt则没有这二者的缺点:
- jwt是在cookie之后发明的技术,设计本身比cookie更安全,浏览器厂商不对jwt进行跨域限制
- jwt通过签名机制,避免了篡改
- 通过非对称加密可以实现分布式验证而无须考虑密钥的一致性,从而加强了跨域的灵活性
- 登录信息编码存储在jwt本身,实现了服务器的无状态
所以jwt比cookie和session更适合用作登录信息验证和跨域验证
其实jwt和cookie比较像
- 都存储在客户端
- 信息是非加密的(cookie是完全明文的,jwt的信息是编码的,jwt的签名是加密的)
- 都能在请求头中(cookie在set-cookie字段,jwt一般在Authorization字段)。
但是jwt相比于cookie是更新更好的技术,用起来方便,所以jwt被广泛运用于用户登录信息验证&跨域验证
而非要纠结技术细节的话,那么我觉得,原理上,cookie是能实现jwt的功能的,但没必要
ps:希望大家也讨论自己的想法