计算机网络-应用层(下)
计算机网络-应用层(下)
xiaoyanJWT 令牌
JWT 令牌和传统方式有什么区别
JWT(JSON Web Token)是一种基于令牌的身份验证机制,与传统的会话管理方式(如Cookie和Session)在多个方面存在显著差异。以下是对JWT令牌与传统方式的详细比较:
1.无状态性
- JWT:JWT是无状态的令牌,服务器不需要在服务器端存储会话信息。JWT令牌本身包含了所有必要的信息,如用户身份、权限等。服务器在用户首次登录时获取用户信息并加密生成JWT令牌,返回给客户端。客户端在后续请求中携带JWT令牌,服务器通过验证令牌来确认用户身份。
- 传统方式(如Session):传统方式通常需要在服务器端存储会话信息。服务器为每个用户生成一个唯一的Session ID,并将其通过Cookie或其他方式传递给客户端。客户端在后续请求中携带Session ID,服务器根据Session ID查找对应的用户状态信息。这种方式需要在服务器端维护会话状态,增加了服务器的负担。
2.安全性
- JWT:JWT使用密钥对令牌进行签名,确保令牌的完整性和真实性。即使令牌在传输过程中被截获,攻击者也无法篡改令牌内容而不被发现。JWT还可以使用加密算法对令牌进行加密,进一步提高安全性。
- 传统方式(如Session):传统方式的安全性依赖于服务器端存储的会话信息。虽然Session数据存储在服务器端,不易受到客户端攻击,但仍然可能存在Session劫持的风险,特别是在Session ID通过不安全的通道(如未加密的HTTP)传输时。
3.跨域支持
- JWT:JWT可以在不同域之间传递,适用于跨域访问的场景。通过在请求头或参数中携带JWT令牌,可以实现无需Cookie的跨域身份验证。JWT的无状态性和自包含特性使其非常适合在分布式系统和微服务架构中使用。
- 传统方式(如Cookie):
传统方式(如Cookie)在跨域访问时存在一定的限制。Cookie通常只能在同一域名下使用,跨域访问需要特殊处理(如CORS配置)。此外,Cookie还容易受到跨站请求伪造(CSRF)攻击,需要采取额外的安全措施。
4。可扩展性
- JWT:JWT的可扩展性非常好,因为JWT是无状态的,服务器不需要存储JWT信息。JWT可以轻松地在分布式系统中使用,适用于大规模和高并发的应用场景。
- 传统方式(如Session):传统方式的可扩展性较差,因为需要在服务器端存储和管理会话信息。随着用户数量的增加,服务器需要维护大量的会话数据,可能会增加服务器的负担。
5.适用场景
- JWT:适用于需要无状态身份验证的场景,如单点登录(SSO)、API访问控制、微服务架构等。JWT的无状态性和自包含特性使其非常适合在分布式系统和微服务架构中使用。
- 传统方式(如Session):适用于需要服务器端存储大量数据的场景,如用户登录状态、购物车信息等。传统方式在需要维护复杂会话状态的应用中仍然有其优势。
JWT 令牌详解
JWT(JSON Web Token)是一种基于令牌的身份验证机制,广泛应用于现代Web应用和API中。JWT令牌是一种紧凑且自包含的方式,用于在客户端和服务器之间安全地传输信息。以下是对JWT令牌的详细解析:
JWT的结构
JWT令牌由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature),这三部分通过.
分隔。
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
1. 头部(Header)
头部通常包含两部分信息:令牌类型(typ)和使用的签名算法(alg)。例如:
1 | { |
alg
:指定使用的签名算法,如HMAC SHA256(HS256)、RSA SHA256(RS256)等。typ
:指定令牌类型,通常为JWT
。
2. 载荷(Payload)
载荷包含实际需要传输的数据,通常包括用户身份信息、权限信息等。载荷可以包含自定义的声明(Claims),也可以包含一些标准声明(Registered Claims)。例如:
1 | { |
sub
:主题(Subject),通常是用户的唯一标识。name
:用户名。iat
:签发时间(Issued At),表示令牌的创建时间。
其他常见的标准声明包括:
iss
:签发者(Issuer)。exp
:过期时间(Expiration Time)。nbf
:生效时间(Not Before)。jti
:JWT ID,唯一标识符。
3. 签名(Signature)
签名用于验证令牌的完整性和真实性。签名是通过将头部和载荷进行Base64编码后,使用指定的算法和密钥生成的。例如,使用HMAC SHA256算法生成签名的过程如下:
1 | HMACSHA256( |
JWT的工作流程
用户登录:用户在客户端输入用户名和密码进行登录,客户端将登录请求发送到服务器。
服务器验证:服务器验证用户的身份,如果验证成功,服务器生成JWT令牌。
生成JWT:服务器将用户信息(如用户ID、权限等)放入JWT的载荷中,使用密钥对头部和载荷进行签名,生成JWT令牌。
返回JWT:服务器将生成的JWT令牌返回给客户端。
客户端存储JWT:客户端将JWT令牌存储在本地(如浏览器存储、本地存储或移动设备)。
后续请求:客户端在后续请求中携带JWT令牌,通常通过HTTP请求头(Authorization: Bearer
)或URL参数传递。 服务器验证JWT:服务器接收到请求后,验证JWT令牌的签名和有效性。如果验证通过,服务器处理请求;否则,拒绝请求。
JWT的优点
- 无状态性:JWT是无状态的,服务器不需要存储JWT信息,适用于分布式系统和微服务架构。
- 安全性:JWT使用签名和加密算法确保令牌的完整性和真实性,防止篡改和伪造。
- 跨域支持:JWT可以在不同域之间传递,适用于跨域访问的场景。
- 可扩展性:JWT的可扩展性非常好,适用于大规模和高并发的应用场景。
JWT的缺点
- 令牌大小:JWT令牌的大小可能会比较大,特别是当载荷中包含大量信息时。
- 无法撤销:JWT令牌一旦签发,除非过期,否则无法撤销。如果需要撤销令牌,通常需要额外的机制(如黑名单)。
- 安全性依赖密钥:JWT的安全性依赖于密钥的安全性,如果密钥泄露,攻击者可以伪造JWT令牌。
JWT 如何解决集群部署问题
传统的请求方式基于Cookie和会话机制,数据信息保存在服务器或数据库中,而在集群部署情况下,每台服务器的数据是独立的,如要实现共享需要额外的共享操作,这就会消耗额外的性能和空间。
而不同于传统方式,JWT令牌是无状态的,会话所需要的数据被加密到令牌当中,这样能够样用户即使切换到新的服务器也不需要再重新登陆,服务器只需要对令牌进行校验解析即可获取到用户的信息。
由于JWT令牌是自包含的,服务器可以独立地对令牌进行校验,而不需要依赖于其他服务器或共享存储,使得集群中的每个服务器都能独立地处理请求,增加集群系统的可伸缩性和容错性。
JWT 缺点
JWT的缺点
无法撤销令牌:JWT令牌一旦签发,除非过期,否则无法撤销。这意味着如果令牌被泄露或需要强制注销用户,服务器无法直接撤销令牌,只能等待令牌自然过期。
令牌大小:JWT令牌的大小可能会比较大,特别是当载荷中包含大量信息时。这可能会增加网络传输的开销,特别是在移动设备或低带宽环境下。
安全性依赖密钥:JWT的安全性依赖于密钥的安全性,如果密钥泄露,攻击者可以伪造JWT令牌。因此,密钥的管理和保护至关重要。
解决方案
- 黑名单策略
为了解决JWT令牌无法撤销的问题,可以采用黑名单策略。具体步骤如下:
- 维护黑名单:服务器维护一个黑名单数据结构(如Redis、内存数据库),用于存储已撤销的JWT令牌。
- 拦截过滤:在处理请求时,服务器首先检查JWT令牌是否在黑名单中。如果在黑名单中,服务器拒绝请求;否则,继续验证令牌的有效性。
- 定期清理:定期清理黑名单中的过期令牌,避免黑名单数据无限增长。
- 设置合理的过期时间
为了减少令牌泄露的风险,可以设置合理的JWT令牌过期时间。较短的过期时间可以降低令牌被滥用的风险,但也会增加用户频繁登录的频率。
- 使用刷新令牌机制
为了平衡安全性和用户体验,可以使用刷新令牌(Refresh Token)机制。具体步骤如下:
- 签发访问令牌和刷新令牌:在用户登录成功后,服务器签发一个短期有效的访问令牌(Access Token)和一个长期有效的刷新令牌(Refresh Token)。
- 使用访问令牌:客户端在后续请求中使用访问令牌进行身份验证。如果访问令牌过期,客户端可以使用刷新令牌向服务器请求新的访问令牌。
- 撤销刷新令牌:如果需要强制注销用户,服务器可以撤销刷新令牌,从而阻止用户获取新的访问令牌。
- 使用HTTPS加密传输
为了防止令牌在传输过程中被截获,建议使用HTTPS加密传输JWT令牌。HTTPS可以确保令牌在传输过程中的安全性,防止中间人攻击。
- 密钥管理
为了提高JWT的安全性,需要采取以下密钥管理措施:
- 使用强加密算法:使用强加密算法(如HS256、RS256)生成JWT,确保令牌的不可伪造性。
- 密钥轮换:定期轮换密钥,避免密钥长时间使用带来的安全风险。
- 密钥保护:确保密钥的安全存储,避免密钥泄露。
JWT 前端存储方案
JWT(JSON Web Token)是目前最流行的跨域认证解决方案之一。客户端收到服务器返回的JWT令牌后,通常需要将其存储在客户端本地。常见的存储方案包括Local Storage、Session Storage和Cookie。以下是对这三种存储方案的详细解析:
- Local Storage
较大的存储空间:Local Storage提供了较大的存储空间(通常为5MB),可以存储较长的JWT令牌。
不会随HTTP请求发送:Local Storage中的数据不会自动随HTTP请求发送到服务器,减少了网络传输的开销。
XSS风险:Local Storage容易受到跨站脚本攻击(XSS)。攻击者可以通过注入恶意JavaScript代码读取存储在Local Storage中的JWT令牌,从而盗取用户身份凭证。
- Session Storage
较大的存储空间:Session Storage同样提供了较大的存储空间(通常为5MB),可以存储较长的JWT令牌。
仅限于当前浏览器窗口:Session Storage中的数据仅限于当前浏览器窗口,关闭窗口后数据会被清除,适合短期存储。
用户体验问题:Session Storage中的数据在刷新网页或关闭窗口后会被清除,导致用户需要重新验证身份,影响用户体验。
XSS风险:Session Storage同样容易受到XSS攻击,攻击者可以通过注入恶意JavaScript代码读取存储在Session Storage中的JWT令牌。
- Cookie
自动发送:Cookie中的数据会自动随HTTP请求发送到服务器,服务器可以方便地验证JWT令牌。
安全性增强:可以通过设置HTTPOnly和Secure属性来提高Cookie的安全性。HTTPOnly属性可以防止JavaScript访问Cookie,减少XSS攻击的风险;Secure属性可以确保Cookie只在HTTPS连接中传输,防止中间人攻击。
存储空间限制:单个Cookie的大小通常限制在4KB左右,并且大多数浏览器对单个域名下的Cookie数量也有一定的限制(通常为20个左右)。
跨域问题:Cookie在跨域访问时存在一定的限制,需要特殊处理(如CORS配置)。
WebSocket
了解WebSocket
WebSocket工作过程
HTTP长连接与WebSocket的区别
HTTP长连接和WebSocket是两种不同的网络通信技术,它们在实现机制、适用场景和性能特点上存在显著差异。以下是对这两种技术的详细比较:
HTTP长连接
HTTP长连接(也称为持久连接或Keep-Alive连接)是基于HTTP协议的一种连接复用技术。在HTTP/1.1中,默认情况下连接是持久的,即客户端和服务器之间的连接在完成一次请求后不会立即关闭,而是保持打开状态,以便后续请求可以复用该连接。
适用场景
- 静态资源请求:适用于频繁请求静态资源的场景,如网页中的图片、CSS、JavaScript文件等。
- 短时间内的多次请求:适用于客户端在短时间内需要多次请求服务器资源的场景。
性能特点
- 减少连接建立开销:通过复用连接,减少了每次请求的TCP连接建立和关闭的开销,提高了网络传输效率。
- 减少延迟:减少了每次请求的往返时间(RTT),降低了网络延迟。
- 适用范围有限:HTTP长连接主要适用于短时间内的多次请求,对于需要长时间保持连接的场景(如实时通信),HTTP长连接并不适用。
WebSocket
WebSocket是一种全双工通信协议,允许客户端和服务器之间进行双向实时通信(TCP协议本身是全双工的,但我们常用的HTTP/1.1虽然基于TCP协议,却是半双工的,因为HTTP是应答模式)。WebSocket协议在HTTP协议的基础上进行升级,通过一次握手过程建立持久连接,之后双方可以通过该连接进行实时数据传输。
适用场景
- 实时通信:适用于需要实时通信的场景,如在线聊天、实时游戏、股票行情等。
- 实时数据推送:适用于服务器需要主动向客户端推送数据的场景,如实时通知、实时监控等。
性能特点
- 全双工通信:WebSocket支持全双工通信,客户端和服务器可以同时发送和接收数据,实现实时双向通信。
- 低延迟:WebSocket连接建立后,数据传输的延迟较低,适合实时通信场景。
- 轻量级协议:WebSocket协议本身较为轻量,数据传输的开销较小,适合高频数据传输。
区别总结
特性 | HTTP长连接 | WebSocket |
---|---|---|
实现机制 | 基于HTTP协议的连接复用技术 | 基于HTTP协议升级的全双工通信协议 |
适用场景 | 静态资源请求、短时间内的多次请求 | 实时通信、实时数据推送 |
通信方式 | 半双工(请求-响应模式) | 全双工(双向实时通信) |
连接保持 | 连接保持时间有限,适用于短时间请求 | 持久连接,适用于长时间实时通信 |
协议开销 | 每次请求需要携带HTTP头信息 | 协议开销较小,适合高频数据传输 |
数据传输延迟 | 每次请求的往返时间(RTT)较高 | 数据传输延迟较低,适合实时通信 |
Nginx
Nginx负载均衡算法
- 轮询:按照请求顺序依次分配给后端请求。这种算法最简单,但无法应对单点缓慢以及用户连续请求情况。
- IP哈希:根据客户端IP地址来计算哈希值,分配到对应的后端服务器,能够保证客户端总能请求到同一台服务器。
- URL哈希:按访问的URL哈希结果来分配后端服务器,可以进一步增加后端服务器缓存的使用率。
- 最短响应时间:根据后端服务器的响应时间来进行分配,响应速度越快的服务器会收到的请求越多,能够充分利用后端服务器的性能,实现负载均衡。
- 加权轮询:按照权重分配请求给后端服务器,权重越高的服务器会收到更多的请求,适用于后端服务器性能不同的情况,提高高性能服务器利用率,实现负载均衡。