【JavaWeb】Session 和 Cookie
Session 和 Cookie
- 会话(Session):用户打开一个浏览器,访问了一些web资源,关闭浏览器,这个过程可以称为一个会话。
- 有状态会话:浏览器能够保存客户端信息的会话。
保存会话
- Cookie:客户端技术(请求,响应),服务器给客户端创建Cookie。是服务器通知客户端保存键值对的一种技术,客户端有了Cookie后,每次请求都会发送给服务器,每个Cookie的大小不能超过4kb
- Session:服务器技术,可以保存用户的会话信息。可以把信息和数据放在session中
为什么需要保存会话?
因为 HTTP 连接是短连接,是无状态的。用户之前登陆过后再次登录时,还需要再次输入用户名和密码信息,因此为了帮用户保存这些信息,需要使用 Session 和 Cookie 技术(或 Token 技术)。
Session 原理
每个客户端(浏览器)在与服务器端产生连接后,都会在服务器端为该客户端创建一个独有的 Session 对象。Session 就是 Tomcat 服务器内存中保存的一个 Map 对象,所有 Session 对象都放到一个 SessionManager
里进行管理,不同的 Session 代表与不同的客户端进行的会话。
Session 和 Cookie 的关系:
- 在某个客户端(浏览器)第一次访问服务器时,将创建一个 Session 对象,并保存到服务器端
- 同时令客户端保存一个
jsessionid = sessionId
的 Cookie。其 key 值是固定的jsessionid
,value 是sessionId
。浏览器关闭前该 Cookie 将一直存在 - Cookie 中还保存着一个重要信息:
Domain
(域名)。该值保存着该 Cookie 可以访问的网站域名。当访问一个网站时,浏览器会从目前存活的所有 Cookie 中选出Domain
匹配当前网站的那些 Cookie,并在访问该网站时在请求头里带上这些 Cookie。 - 之后 Cookie 存在期间每次访问对应
Domain
的服务器都将带上 Cookie 信息(在请求头中) - 浏览器关闭后,清除掉 Cookie,服务器端清除掉 Session
Cookie 是浏览器负责保存,Session 是服务器负责保存。Cookie 中保存着 Session 信息,对应唯一的一个 Session。
示意图:
Session 安全性
问题:如果黑客随意编写 Session ID,不就能登录任意用户的账号了吗?
加签和验签可以解决该问题。
- 加签:服务器在发送 Cookie 之前对这个含有 Session ID 的 Cookie 进行签名,生成一个签名 sign 一同发送给浏览器,也作为该域名下的一个 Cookie。
- 验签:当浏览器再发送请求时,服务器会先验证该请求携带的 Cookie 中,签名 sign 能否匹配上 Session ID。如果能匹配,则认证成功;否则,认证失败,拒绝访问。
支付宝的支付服务同样有加签和验签步骤保证数据安全性。
Cookie
服务器创建Cookie
服务器获取客户端的Cookie
- 从请求中拿到Cookie信息
- 服务器响应给客户端Cookie
1 | Cookie[] cookies = req.getCookies(); // 获得cookies |
删除Cookie的方法:
- 不设置有效期,关闭浏览器(关闭Session),自动失效;
- 设置有效期,时间为0。
Cookie有效路径Path的设置:通过设置path路径可以过滤掉不符合路径的Cookie。
Session
服务器会给每一个用户(浏览器)创建一个Session对象。一个Session独占一个浏览器,只要浏览器没关,这个Session就一直存在。用户登录之后,整个网站都可以访问到用户信息。
Session技术,底层是基于Cookie技术实现的:每次创建出的Session对象都会保存成一个Cookie对象传给浏览器保存(该Cookie对象的生命周期为Session级别,即关闭浏览器后销毁)。
Session和Cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session是把用户的浏览器写到用户独占的Session中,服务器保存(保存重要的信息,减少资源的浪费)
- Session对象由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常用到的数据
1 | // 在session中存入信息 |
Session销毁方法:
- 手动销毁:
1 | getSession().invalidate(); |
- 自动销毁:设置会话自动过期:web.xml配置
1 | <session-config> |
分布式 Session
关于分布式 Session 的详细介绍见文章http://blog.yuyunzhao.cn/2021/12/20/%E3%80%90Spring%E3%80%91SpringSession/
JWT
如果某些客户端不支持 Cookie,那么上述方法也就失效了。并且基于 Session Cookie 方式的存储方法会对服务器造成一定的性能损耗。因此需要引入一种新的技术来解决存储问题:JWT。
关于 JWT 的介绍和使用见文章 【JavaWeb】JWT