Cookie 和 Session
Session 和 Cookie
- Cookie
- 1. Cookie 是什么?
- 2. Cookie 的结构
- 3. Cookie 的不可跨域名性
- 4. Cookie 的有效期
- 5. Cookie 的修改、删除
- Session
- 1. 什么是 Session
- 2. Session 的存储位置
- 3. Session 的有效期
Cookie
1. Cookie 是什么?
当我们打开登陆过的网站时不用重新输入密码,是因为客户端保存了之前登录时获取的凭证(token/session),并且这个凭证还在有效期内,服务器通过凭证来识别我们
那如果没有这个凭证,每一次登录网站都要重新输入密码就会很麻烦
会话(Session):指用户从打开网站到关闭浏览器、或者从登录到退出登录的这一段连续交互过程
会话跟踪(Session Tracking):就是在 无状态的 HTTP 协议 上,让服务器能够识别并跟踪用户整个会话过程
HTTP 是 无状态协议,每一次请求都是独立的,服务器处理完请求后退出,再次需要请求时,还要重新建立新的连接。就是上面说的每一次登录都要重新输入密码,这带来了很多麻烦。Cookie 就是为了解决这个问题而诞生的
定义:Cookie 是存储在 浏览器本地 的一小段文本数据,每次请求时会自动携带到服务器,从而实现状态保持
可以把它想象成:网站留在你浏览器里的“小纸条”,带着它去访问网站,服务器就能认出你
2. Cookie 的结构
一个 Cookie 通常包含以下属性:
- Name / Value:键值对,存储的核心内容
- Domain:作用域域名,比如 .example.com
- Path:生效路径,比如 /user
- Expires / Max-Age:过期时间
- Secure:只允许在 HTTPS 下传输
- HttpOnly:禁止 JS 访问,防御 XSS 攻击
- SameSite:控制跨站点请求时是否携带 Cookie
3. Cookie 的不可跨域名性
很多网站都会用到 cookie,Cookie 默认是 绑定在某个域名下的。
意思是,我们访问 a.com
的时候只会 携带或操作 a.com
的 cookie,但是不会 携带或操作b.com
的 cookie,反过来也是,从而保证用户的隐私安全
Cookie 在客户端是由浏览器来管理的。浏览器判断一个网站是否能操作另一个网站 Cookie 的依据是域名,域名不一样就不能操作
为什么不能跨域?
这是 浏览器安全策略(同源策略) 的一部分。
如果允许 Cookie 跨域,那 a.com
就能拿到你在 b.com
的 Cookie,这样会话信息、登录状态就全暴露了
所以 Cookie 必须绑定域名,不能随便跨站传递
4. Cookie 的有效期
Cookie 的有效期与 maxAge 有关(单位为秒),Cookie中通过 getMaxAge() 方法与 setMaxAge(int maxAge) 方法来读写 maxAge 属性
maxAge 分为以下几种情况:
1. MaxAge > 0(正数)
表示从当前时刻起,cookie 还能存活 N 秒。期间浏览器会一直保存(写入磁盘),即使关闭/重启也会带上。
到了 N 秒后,浏览器自动删除
示例:
Set-Cookie: token=abc123; Max-Age=3600; Path=/; HttpOnly; Secure
意思是:token 有效 1 小时。
2. MaxAge = 0
表示 cookie 立即过期,浏览器立刻删除这个 cookie
示例:
Set-Cookie: token=; Max-Age=0; Path=/; HttpOnly
意思是:删除名为 token 的 cookie
注意:删除时 Path
、Domain
要和原来保持一致,否则删不掉
3. MaxAge < 0(负数)
表示该 Cookie 仅在本浏览器窗口以及本浏览器窗口打开的子窗口内有效,浏览器关闭(或会话结束)时删除。 代表着 cookie 不是持久化的,Cookie 信息不会写入硬盘,而是保存在浏览器内存中
示例:
Set-Cookie: theme=dark; Max-Age=-1; Path=/
意思是:这是一个会话 cookie,关闭浏览器就没了
5. Cookie 的修改、删除
Cookie 不提供修改、删除操作
修改 Cookie:新建一个同名的 Cookie,添加到 response 中覆盖原来的 Cookie
删除 Cookie:新建一个同名的 Cookie,将 maxAge 设置为 0,添加到 response 中覆盖原来的 Cookie
注意:修改、删除 Cookie 时,新建的 Cookie 除了 value、maxAge 之外的所有属性,都要与原来的 Cookie 完全一样,否则就是两个不同的 Cookie,没办法覆盖
Session
1. 什么是 Session
Session(会话) 是服务器端保存的用户状态(记录用户状态)
通常在用户登录后,服务端会创建一份 Session 数据(比如用户名、权限等),并生成一个唯一 ID(Session ID)。这个 Session ID 会通过 Cookie 或 URL 参数传给客户端,客户端之后的请求就带上这个 ID,服务端根据它找到对应的用户数据
与 Cookie 不同的是:
存储位置不同
- Cookie 存在于客户端浏览器里(相当于让用户自己保管一张小纸条)
- Session 存在于服务器端(相当于商家自己保存了顾客的档案,只给顾客一张“编号”凭证)
安全性不同
- Cookie 数据直接放在浏览器里,用户有可能篡改或窃取
- Session 数据存放在服务器里,更安全,用户手上只有一个 session ID(通常通过 Cookie 携带)
存储大小限制
- Cookie 受浏览器限制,通常只有几 KB 大小
- Session 在服务器端,理论上只要服务器资源足够,能存储更多数据
生命周期不同
- Cookie 可以设置过期时间,甚至“记住我”保存几个月
- Session 一般在浏览器关闭或超时(默认 30 分钟)后就失效,需要重新登录
2. Session 的存储位置
Session 存储在 服务端内存 中。每个用户都有一个独立的 Session,如果 Session 过于复杂,当大量客户访问服务器时可能导致内存溢出,所以 Session 里面的信息应该尽量精简
3. Session 的有效期
Session 从创建到销毁,大致可以分为以下几个阶段:
-
创建阶段
当用户第一次访问服务器时,服务器会创建一个新的 Session,并分配一个唯一的 Session ID。这个 Session ID 一般会通过 Cookie(名字通常叫 JSESSIONID 或 sessionid)传回给浏览器 -
使用阶段
在用户的后续请求中,浏览器会自动带上 Session ID(通常放在 Cookie 中)。服务器就能根据这个 ID 找到对应的 Session 数据,识别用户身份。用户每访问一次服务器,服务器就会更新 Session 的最后访问时间,并维护该 Session,认为该用户的 Session **活跃(active)**了一次 -
过期阶段
Session 不是永久保存的,它有一个 默认有效期,常见是 30 分钟
随着越来越多的用户访问服务器,Session 也会越来越多。为了防止内存溢出,服务器会把长时间没有活跃的 Session 从内存中删除,这个 Session 就会失效
一旦失效,服务器会销毁该 Session,用户需要重新登录才能重新生成新的 Session -
销毁阶段
除了自动过期,Session 还可以手动销毁,Session的超时时间为maxInactiveInterval
属性,可以通过对应的getMaxInactiveInterval()
获取,通过setMaxInactiveInterval(longinterval)
修改。
Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()
方法可以使Session失效。
补充:前面提到了 Session ID 会通过 Cookie 或 URL 参数传给客户端,但是很多用户的浏览器不支持 Cookie,那直接建立统一标准,禁止 Session 使用 Cookie,统一使用 URL 地址