cookie:
Cookie 是一种由服务器发送并存储在用户浏览器上的小型数据文件。每次用户向服务器发送请求时,Cookie 会随请求一起被发送到服务器。Cookie 用于存储小量的信息,如用户的登录状态、语言偏好等。
为什么使用cookie
HTTP:超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。
web程序是使用HTTP协议传输的,而HTTP协议是无状态的协议,对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快
特点:
-
存储位置:数据存储在客户端(浏览器)中。
-
生命周期:可以设置过期时间,或者在浏览器会话结束后删除(会话 Cookie)。
-
传输方式:每次向服务器发送请求时,Cookie 数据会自动包含在 HTTP 请求的头部。
-
安全性:数据存储在客户端,可能被恶意用户篡改或窃取。
优点:
-
减轻服务器负担:数据存储在客户端,服务器无需存储用户的每个会话数据。
-
方便管理:可以存储用户偏好设置、登录状态等信息,方便用户使用同一设备时自动登录。
-
跨会话存储:Cookie 可以持久化存储,在多个会话之间保持数据。
缺点:
-
存储大小有限:每个 Cookie 的大小通常限制在 4KB 左右,存储数据量非常有限。
-
安全性差:因为存储在客户端,容易受到 XSS(跨站脚本攻击)等安全漏洞的影响,恶意用户可能窃取或篡改 Cookie 数据。
-
隐私问题:由于 Cookie 存储在用户的浏览器中,可能被第三方网站或广告商用来追踪用户行为,侵犯隐私。
-
跨域问题:Cookie 只能在同一域名下有效,无法跨域传递,限制了其在多个网站之间共享数据的能力。
session
Session 是一种在服务器端存储用户信息的机制。每次用户访问网站时,服务器为用户创建一个唯一的会话标识符(通常是一个随机生成的ID),并将用户相关的状态信息存储在服务器上。该会话ID会通过 Cookie 或 URL参数 的形式传递给客户端。
特点:
-
存储位置:数据存储在服务器端。
-
生命周期:通常是用户会话的生命周期,也可以通过设置过期时间来限制。
-
传输方式:通过 Cookie 或 URL 来传递 Session ID。
-
安全性:由于数据存储在服务器端,安全性较高,不容易被篡改。
优点:
-
更安全:由于数据存储在服务器端,客户端无法直接访问或篡改数据。
-
无需暴露敏感信息:Session ID 是客户端的唯一标识符,数据本身存储在服务器,不会暴露在浏览器中。
-
可以存储大量数据:因为数据存储在服务器端,所以可以存储比 Cookie 更大的数据量。
缺点:
-
性能问题:每次请求都需要访问服务器存储的数据,随着用户量的增加,可能导致服务器负担增大。
-
服务器负担:服务器需要维护大量的 Session 信息,消耗内存和存储空间。
-
需要共享服务器状态:在分布式系统中,多个服务器间需要共享 Session 数据(通过数据库或共享存储),增加了复杂性。
JWT
JWT(JSON Web Token) 是一种开放标准(RFC 7519),用于在网络应用环境中安全地传递信息。JWT通常用于身份认证和信息交换,它通过数字签名来确保信息的安全性和完整性。
结构:
JWT 是由三部分组成的字符串,通常用点号(.
)分隔:
-
Header(头部):包含令牌的类型(通常是JWT)和使用的签名算法(如HMAC SHA256或RSA)。
-
例如:
{ "alg": "HS256", "typ": "JWT" }
-
-
Payload(有效载荷):包含你要传递的数据,通常是关于用户的声明(Claims)。例如,用户ID、权限等。注意,JWT的payload部分不加密,因此数据可以被解码查看,但不能被篡改。
-
例如:
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
-
-
Signature(签名):确保数据在传输过程中不被篡改。为了生成签名,需要使用header和payload的编码字符串,以及一个密钥(对于对称加密的HMAC算法)或私钥(对于非对称加密的RSA算法)。签名部分可以用来验证JWT的来源和完整性。
-
例如,使用HMAC SHA256算法签名:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)//secret不会在网络中传输,所以客户端不能伪造JWT
-
特点:
-
无状态:JWT 是无状态的,意味着服务器不需要存储会话信息。所有用户信息都保存在 JWT 中,用户的每次请求都携带 JWT,服务器仅需验证 JWT 是否有效即可。
-
跨平台支持:JWT 是基于 JSON 的格式,可以被大多数编程语言和框架所支持,具有很强的跨平台特性。
-
自包含:JWT 包含了所有的信息(如用户身份、权限等),因此,用户每次请求时,服务器无需访问数据库查询相关信息,减轻了服务器的负担。
-
安全性:JWT 可以使用对称加密(如 HMAC)或非对称加密(如 RSA、ECDSA)进行签名,确保数据在传输过程中不会被篡改。
优点:
-
无状态认证:JWT 通过将用户的身份信息存储在 Token 中,避免了服务器端存储用户会话的需求。每次请求都可以携带 JWT 进行身份验证,从而减轻了服务器的负担。
-
高效的传输方式:JWT 是一个 URL 安全的字符串,适合在 HTTP 请求的 Authorization 头部传递,支持跨域认证。
-
易于扩展:JWT 可以根据需求自定义负载部分(Payload),例如,存储用户的角色、权限等信息,灵活性很高。
-
跨平台支持:由于 JWT 是 JSON 格式的,它具有广泛的跨平台兼容性,可以在不同的技术栈中使用,如 Java、JavaScript、Python、PHP 等。
-
可以使用标准加密算法:JWT 支持多种加密算法(如 HMAC、RSA),用户可以根据需求选择合适的算法保证数据安全。
-
避免频繁的数据库访问:由于所有用户信息都存储在 JWT 中,服务器无需每次都查询数据库,从而减少了数据库的访问压力。
缺点:
-
不支持撤销机制:JWT 是自包含的,一旦签发,就无法修改或撤销,除非令牌过期或被明确地删除。这意味着,如果用户的权限发生变化(例如用户退出登录、用户被禁用),服务器端无法主动撤销 JWT,需要依赖 JWT 的过期时间。
-
较长的生命周期风险:如果 JWT 的有效期设置过长,可能会带来安全隐患。如果一个 JWT 被泄露,攻击者就可以在有效期内无限期地使用它。因此,需要谨慎设置 JWT 的过期时间。
-
负载暴露:JWT 的负载部分是可以解码的,即使它是加密签名的,也可以被任何人查看。虽然签名能够保证数据的完整性,但是负载中的信息(如用户信息、权限等)仍然可以被读取。所以,对于敏感信息,JWT 应该采用加密而非仅签名。
-
较大的体积:JWT 包含了头部、负载和签名,可能会导致 Token 相对较大,特别是在包含大量信息时,可能会增加网络传输的负担。
-
没有内置的过期处理:JWT 只提供了过期时间字段(exp),但是它并没有提供对 Token 的自动注销功能,因此需要额外的机制来处理注销和刷新。
使用场景:
-
身份验证:JWT 常用于 Web 应用的用户登录认证。用户登录成功后,服务器生成一个 JWT 令牌,并返回给客户端,客户端将其保存在本地(通常是浏览器的 localStorage 或 cookie)。之后的每次请求,客户端都会携带 JWT 进行身份验证。
-
授权:JWT 还可以用于授权控制,服务器根据 JWT 中的声明信息来确定用户是否有权访问特定的资源或执行某些操作。
-
信息交换:JWT 可用于应用间的安全信息交换,因为 JWT 是自包含的,携带的信息可以在不同的服务和系统之间传递。
cookie和session区别/session和cookie的区别及各自优缺点
安全性:
-
Session 比 Cookie 安全,Session 是存储在服务器端的,服务器会为每个用户维护一个 Session 对象,客户端只有一个与之关联的标识符(通常是 Session ID)
-
Cookie 是存储在客户端(浏览器)的,容易受到客户端攻击(如跨站脚本攻击、窃取 Cookie 等)。为了提高安全性,可以使用 HttpOnly 和 Secure 属性来限制 Cookie 的访问,如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。
存取值的类型不同:
-
Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
有效期不同:
-
Cookie 可以设置一个到期时间,过期后会被自动删除。如果没有设置过期时间,它会是会话级的 Cookie,在浏览器关闭时会被删除
-
Session 会在服务器端存储,通常会在浏览器关闭时或会话超时后失效。服务器会通过 Session ID 来维护会话。
存储大小不同:
-
Cookie:浏览器对每个域名的 Cookie 大小有限制,通常每个 Cookie 的大小不超过 4 KB,而且浏览器通常对每个域名的 Cookie 数量也有限制(例如 20 个)。
-
Session:Session 存储在服务器上,可以存储更大的数据量,但受服务器内存或存储限制影响,通常没有像 Cookie 那样的大小限制Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。
-
Session 存储在服务器端,适合存储会话期间的数据,安全性较高。
使用场景
-
Cookie:主要适合存储小量的、非敏感的、需要跨会话持久化(如用户登录状态、语言设置等)、长期有效的数据,用于存储客户端的偏好设置、用户身份验证信息、跟踪用户行为等。
-
Session:更适合需要大量数据存储的场景,主要用于存储用户的会话状态(例如用户登录状态、购物车内容等)。Session 更适合存储需要在整个会话期间使用的数据,且对安全性要求较高的数据。
特性 | Cookie | Session |
---|---|---|
存储位置 | 客户端(浏览器) | 服务器端 |
安全性 | 较低,数据存储在客户端,容易被篡改或窃取 | 较高,数据存储在服务器端 |
存储类型 | 只支持存字符串数据 | 任意数据类型 |
存储容量 | 每个 Cookie 大小限制在 4KB 左右 | 可以存储大量数据,但受服务器内存或存储限制影响 |
性能 | 减轻服务器负担,但每次请求都需要发送到服务器 | 需要服务器维护,可能导致性能问题 |
生命周期 | 可以设置过期时间,或者会话结束时删除 | 会话结束后失效,或由服务器设置过期时间 |
跨域性 | 只能在同一域名下有效,跨域受限 | 需要在多个服务器之间共享 Session 数据 |
cookie和session是怎么协作的?
-
Session ID 存储在 Cookie 中
-
当用户第一次访问网站时,服务器会创建一个新的 Session,并生成一个唯一的 Session ID。
-
服务器将该 Session ID 通过 Cookie 发送到客户端。通常,Cookie 会包含一个名为
JSESSIONID
(或类似名称) 的字段,里面保存着 Session ID。 -
客户端(浏览器)会自动将这个 Cookie 存储在本地,并在后续的每次请求中将其发送到服务器。
-
-
客户端发送 Cookie 到服务器
-
每次用户访问网站时,浏览器会自动携带存储在本地的 Cookie 信息(包括 Session ID)。
-
服务器接收到请求后,从 Cookie 中读取 Session ID,并根据该 Session ID 在服务器端查找相关的会话数据。
-
-
服务器端的会话数据
-
服务器使用 Session ID 来检索存储在服务器上的会话数据(如用户认证状态、用户信息、购物车内容等)。
-
如果会话有效,服务器可以根据这些信息做出响应。例如,验证用户是否已登录,或者返回用户的个性化内容。
-
-
Session 数据的生命周期
-
会话数据通常会在一定的时间内保持有效。如果 Session 超过了设定的有效期,服务器会删除该会话数据,并且客户端的 Cookie 也会失效。
-
可以设置 Cookie 的过期时间,控制 Session 在客户端的存储时长。
-
如果客户端把cookie给禁用了,session还能用吗?
当客户端启用 Cookie 时,浏览器会自动将存储在 Cookie 中的 Session ID 随每个请求发送到服务器,服务器利用这个 ID 查找对应的 Session 数据,从而识别用户身份。如果客户端禁用 Cookie,浏览器就不能发送 Session ID,也无法依赖 Cookie 来维持会话。这种情况下,服务器无法通过请求头中的 Cookie 来识别用户,导致每次请求都会被认为是新的会话,服务器无法关联到先前的 Session 数据。
可以考虑通过 URL 参数传递 Session ID 或使用其他存储方式来实现会话管理。
服务器可以通过 URL 参数 来传递 Session ID。比如,当用户访问某个页面时,URL 可以变成 http://example.com/page?sessionid=12345
,然后服务器根据 URL 中的 sessionid
参数来识别会话。
这种方法虽然可以绕过 Cookie,但不太推荐,因为:
-
它增加了 URL 长度,可能会影响可读性和用户体验。
-
而且Session ID 会暴露在 URL 中,增加了安全风险,容易遭受 URL 注入攻击 或 Session 劫持。
除了 Cookie 外,HTML5 提供了localStorage和sessionStorage,它们也可以在客户端存储数据。如果浏览器禁用 Cookie,可以考虑用这些技术存储 Session ID。不过,这些方法也有一些限制:
-
localStorage
和sessionStorage
只在客户端有效,不会自动随每个请求发送到服务器,因此服务器端依然需要通过某种方式来获取 Session ID。 -
这些存储方式不支持跨不同的浏览器和设备,不能像 Cookie 一样在不同设备或浏览器之间共享数据。
在实际开发中,通常建议用户启用 Cookie,以便 Session 可以顺利工作。