SpringMVC会话机制之Cookie和Session用法及说明
引言
1,什么是会话?
用户打开浏览器,访问网站的多个资源,直到关闭浏览器的整个过程中,称为一次会话。
会话的核心需求:保存用户状态,让服务器识别同一用户的连续请求。
2,HTTP无状态特性
HTTP协议默认不保存请求状态,每次请求都是独立的,服务器不会记录上一次的用户操作。
Cookie和Session就是为了弥补HTTP无状态缺陷而生的会话跟踪技术
3,为什么需要Cookie和Session?
HTTP无状态,无法识别用户身份,无法实现登录保持,用户个性化数据存储等功能,二者配合实现Web端用户会话状态管理。
一,Cookie详解(客户端会话技术)
1,Cookie定义
Cookie是由服务端生成,发送给客户端,由客户端保存在本地的数据(键值对格式)。
浏览器自动存储Cookie后,后续每次请求都会自动携带Cookie到服务器,实现用户的身份识别。
2,Cookie的核心特性*
- 存储位置:客户端浏览器本地
- 数据格式:仅支持字符串(Ascll字符串),无法存储对象
- 大小限制:单个域名的Cookie的总大小小于等于4KB,数量有限
- 生命周期:分为临时Cookie(浏览器关闭就销毁),持久Cookie(设置expires/max - age)过期自动删除
- 自动携带:同域名下所有请求会自动携带Cookie,无需手动传参
- 安全性:安全性比较低,可被客户端查看,篡改,窃取
3,Cookie的关键属性*
Domain:指定Cookie生效域名,默认当前域名,可实现子域名共享
什么叫子域名?

Path:指定Cookie生效路径,默认根路径
Max - Age / Expires:设置过期时间,控制持久化
Secure:开启后,仅HTTPS加密请求会携带Cookie
HttpOnly:禁止JS读取Cookie,防止XSS攻击(核心安全配置)
解释:XSS(跨站脚本攻击):攻击者会往页面里植入恶意JavaScript代码。如果这段代码能读到你的Cookie,就可以把登录凭证给偷走。给Cookie加上HttpOnly之后,浏览器就会禁止JS读取这个Cookie
SameSite:防止CSRF跨站请求伪造攻击
解释:CSRF(跨站请求伪造):比如你登录了A网站(比如银行),然后去点击恶意网站B的链接,B网站让你的浏览器向A网站发送请求(比如转账),浏览器会自动带上A网站的Cookie,导致转账成功。在这个过程中,你的登录凭证就像一张通行证,SameSite规定:只有从原网站进来的才能用这张通行证,其他网站进来的一律不认。
4,Cookie应用场景
记住登录状态,用户偏好设置,页面浏览记录,轻量级标识存储
三,Session详解(服务端会话技术)
1,Session定义
Session是服务端的会话对象,服务器为每一个独立用户创建唯一的Session空间,用于存储用户的会话数据(登录信息,权限,业务数据)。
2,Session特性*
- 存储位置:服务器端(内存 / Redis / 数据库)
- 数据格式:支持任意数据类型(对象,集合,字符串)
- 大小限制:无严格限制,受服务器资源影响
- 生命周期:默认超时销毁,服务器重启,手动销毁也会失效;浏览器关闭不会销毁Session(但是会导致客户端的SessionID消失)
- 安全性:安全性高,用户无法直接操作服务端Session数据,仅通过SessionID关联
- 状态特性:有状态,占用服务器内存资源
3,Session工作核心:SessionID
服务器创建Session后会生成唯一的SessionID,通过Cookie下发到客户端,客户端后续请求携带该Cookie,服务器通过SessionID匹配对应的服务端Session,从而识别用户。
四,Cookie和Session完整工作流程
1,首次请求(无会话)
1,客户端首次请求服务器接口,没有任何Cookie数据

没有访问服务器之前可以看到Cookie为空
2,服务器接收请求,识别新用户,创建专属Session对象,生成唯一SessionID

框中参数为true代表如果么有Session就自动创建Session
3,服务器通过Set - Cookie响应头,将SessionID发送给客户端,客户端保存该Cookie

2,后续请求(会话生效)
- 客户端每次请求同域名接口,自动携带包含SessionID的Cookie
- 服务器解析Cookie中的SessionID,匹配对应的服务端Session
- 读取Session中国存储的用户数据,完成身份识别和状态保持
3,会话失效
服务器Session超时,主动销毁,服务器重启,会话结束;客户端Cookie过期或者清空,也会断开会话关联。
问:浏览器关闭后,Session会失效吗?
答:不会。1,浏览器关闭只会销毁临时Cookie(存储SessionID和Cookie),不会删除服务器端的Session数据。2,服务器端Session会一直存在,直到达到超时时间(默认是30min),除非手动销毁或者服务器重启。3,关闭浏览器后再访问,因本地SessionID Cookie丢失,无法匹配原有Session,看似失效,实则服务端Session依然存在。
问:如果浏览器禁用Cookie,Session还能用吗?如何解决?
答:默认不能用,但可手动解决。1,常规Session依赖Cookie来存储SessionID,禁用Cookie后,客户端无法携带SessionID,无法匹配会话;2,解决方案:URL重写,将SessionID拼接在请求URL中,服务器解析URL中的SessionID完成会话匹配。3,缺点:URL会暴露SessionID,安全性较低。
问;Cookie和Session哪个更安全?为什么?
Session更安全。1,Cookie数据存储在客户端,用户可以直接查看,修改,窃取,容易发生XSS,CSRF攻击;2,Session核心数据存储在服务端,客户端存储唯一的SessionID,即使ID泄露,没有对应的服务端数据权限,风险更低。
问:传统Session存储在单服务器内存,在集群环境下,用户请求被分发到不同服务器,Session不共享,会出现登录失效,状态丢失问题(Session共享问题)
解决方案:
- 1,Session持久化:将Session数据存入Redis,数据库,实现多服务器共享
- 2,负载均衡黏包:固定用户请求分发到同一台服务器(缺点:单点故障,负载不均);
- 3,替代方案:前后端分离项目使用Token / JWT替代传统Session,无状态,适配分布式
问:如何实现 “记住我” 功能?
普通登录:使用临时Cookie,浏览器关闭即失效,Session短期有效
记住我:设置持久化Cookie,延长Cookie过期时间,长期保存用户标识,无需重复登录。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
springboot如何接收application/x-www-form-urlencoded类型的请求
这篇文章主要介绍了springboot如何接收application/x-www-form-urlencoded类型的请求,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11


最新评论