一、什么是JWT
JWT(JSON Web Token)是一个开放标准(RFC 7519)定义的方式,用于在各方之间安全地传输信息。这些信息可以是验证、授权、信息交换等。JWT 允许在请求之间安全地传输信息,因为信息是经过数字签名的,并且可以被验证和信任。JWT 通常用于实现无状态的、基于令牌的认证。
二、JWT的组成
1.Header(头部)
Header(头部):描述了 JWT 的元数据,比如使用的签名算法(HMAC SHA256, RSA 等)。
{
"alg": "HS256", // 指定签名算法为HMAC SHA256
"typ": "JWT" // 指定类型为JWT
}
这个 JSON 对象会被 Base64Url 编码,形成 JWT 的第一部分。
2.Payload(负载)
Payload(负载):包含了声明(claims)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型:registered, public, 和 private。
- Registered claims: 这些是一组预定义的声明,不是强制的,但是推荐。如:iss (issuer), exp (expiration time), sub (subject), aud (audience), 等。
- Public claims: 可以包含任何信息,但应避免冲突与注册的声明。
- Private claims: 用于在同意使用它们的各方之间共享信息。
{
"sub": "1234567890", // JWT的所有人(用户ID)
"name": "John Doe", // 用户的名字
"admin": true, // 用户是否为管理员
"iat": 1516239022 // JWT的签发时间
}
这个 JSON 对象也会被 Base64Url 编码,形成 JWT 的第二部分。
3. Signature(签名)
Signature(签名):是对前两部分(Header 和 Payload)的签名,以防止数据被篡改。签名需要一个密钥(secret)或公钥和私钥对。
三、为什么要使用JWT
因为HTTP协议是无状态的,所以我们登录之后,再次向服务器发送请求,服务器是不知道这个请求是谁发送的。我们可以在登录成功后,将用户ID返回给前端,下次请求时携带这个信息再发送请求,这样服务器就知道每次发送请求的用户了。
这样看上去挺好的,但是有一个问题是服务器是无法信任这个信息的。为什么无法信任?因为这个信息存在客户端,是有极有可能被篡改或者伪造的,服务器无法知晓这个信息是之前自己给颁发的还是伪造或者经过篡改的。总之问题的根源就是:这个信息无法被服务器验证,服务器不能验证这个信息的真假,从而导致服务器无法信任这个信息。
如何解决这个信任的问题呢?我们过去用cookie+session的方式,这种方式是可以解决这个问题的。比如服务器存一个session,后端将session_id设置到HTTP响应的cookie中,并发送给前端。这里可以设置cookie的多个属性,如域名、路径、有效期、安全标志(HTTPS)、HttpOnly等,以提高安全性。下次浏览器发送请求的时候,携带这个session_id,服务器在自己内存里面去找看有没有对应的session。
cookie+session模式的优缺点:
优点:
- 扩展性和可用性:通过良好的编程,可以控制保存在cookie中的session对象的大小,实现较高的扩展性和可用性。
- 安全性:使用加密和安全传输技术(如SSL),可以减少cookie被破解的可能性。同时,由于Session是保存在服务器端的,因此不存在敏感信息泄露的风险。
缺点:
- 依赖性和单点风险:如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量。此外,如果使用了持久化session数据的方法(如写入数据库或文件持久层),那么依赖于这些持久层的数据库或文件系统可能会成为单点风险。
- 分布式架构支持:在分布式架构或面向服务的跨域体系结构下,session的共享和同步可能成为一个问题。需要使用如Redis或Memcached等外部存储系统来实现session的共享。
- 服务器压力问题:将session存在服务器上,如果登录用户过多,会增加服务器的存储压力。
如果使用JWT的话,可以避免cookie+session模式下存在的这些问题。因为jwt是存在于客户端的,减轻了服务器存储的压力,同时在分布式架构或面向服务的跨域体系结构下也可以很好的使用。
jwt是服务器把要发送给前端的信息用一个密钥来加密,生成一个签名,然后把信息(jwt)返回给前端。这样做可以防止伪造和篡改吗?
当然可以。假如把JWT中的信息部分(负载部分)进行了修改,然后发送到服务器,服务器验证是通过不了的。因为签名部分是根据负载部分用密钥进行加密的,修改负载部分之后,服务器用存储在服务器端的密钥再次对负载部分进行加密,加密后的结果再和jwt中的签名部分进行比对,这样是对不上的,所以验证是通不过的。
那如果把负载部分和签名部分都同时进行修改呢?因为签名部分是根据负载部分的信息,使用密钥进行加密的,而密钥是存在于服务器的,不存在于前端的,你拿不到这个密钥。没有办法拿到这个密钥的话,就没有办法修根据修改后的负载信息生成正确的签名。
jwt的优缺点
优点:- 无状态性:JWT是无状态的,服务器不需要保存任何关于客户端的会话信息,这使得JWT非常适合分布式系统和微服务架构。
- 可扩展性:JWT的有效载荷可以包含任意数据,可以根据需求添加自定义的用户信息,如权限等。
- 跨平台性:JWT是基于JSON格式的标准,可以被多种编程语言支持和解析。
缺点:
- 无法撤销:一旦JWT签发后,无法撤销或更改其内容。如果需要在JWT的有效期内提前使其失效,需要额外的处理。
- 动态更新性:由于JWT的无状态性,当用户的信息或权限发生变化时,服务器需要重新签发一个JWT。这可能会导致系统需要额外的处理来控制JWT的过期时间和更新机制。 令牌大小:由于JWT包含了许多信息和签名,因此它在网络传输中的大小可能比传统的会话ID要大。
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » JWT理论介绍
发表评论 取消回复