【前端知识】Cookie, Session,Token和JWT的发展及区别(二)
- 4. Session
- 4.1 Session的背景及定义
- 4.2 Session的特点
- 👍4.2.1 Session的特点
- 👀4.2.2 Session保存的位置
- 4.3 Session的一些重要/常用属性
- 4.4 Session的认证流程
- 4.5 Session的优缺点
- 😎4.5.1 优点
- 🤢4.5.2 缺点
- ✍4.5.3 作用及常用场景
- 4.6 Session可能带来的问题
- 4.7 Session的作用域及相关思考
- 4.7.1 Session的作用域
- 4.7.2 当客户端关闭后,服务端不关闭,两次获取Session是同一个?
- 4.7.3 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
- 4.7.4 Session什么时候被销毁?失效时间?
- 5. Cookie与Session的区别及相关知识点
- ✨ 5.1 区别
- 🤔 5.2 一个思考:既然盗取了Cookie,无论是Session还是Cookie都一样会被冒充,那为什么需要Session呢?
- 6. 下篇章笔记
五一假期第4天,继续上篇笔记的分享啦。本文为原创,未经同意请勿转载
由于篇幅有点长😂,所以笔者将我关于这部分的笔记分为四个篇章(文章开头后面附录上下篇链接),避免读者的阅读疲倦感😵,同时也方便大家的阅读啦🤗。如果下面笔记中存在错误,欢迎大家及时指正,学习与讨论。
- 上章:主要介绍一下背景和Cookie。
链接:【前端知识】Cookie, Session,Token和JWT的发展及区别(一) - 中章:主要介绍一下Session并总结一下Cookie和Session。
链接:【前端知识】Cookie, Session,Token和JWT的发展及区别(二) - 下章:主要介绍Token的相关定义及理解
链接:【前端知识】Cookie, Session,Token和JWT的发展及区别(三) - 终章:主要介绍JWT并总结JWT和Token的区别,以及总结Cookie到Token的区别与发展。
链接:【前端知识】Cookie, Session,Token和JWT的发展及区别(四)
4. Session
4.1 Session的背景及定义
虽然Cookie机制可以让服务器与浏览器相互认识,但是因为Cookie是保存在客户端的,所以Cookie被入侵窃取的风险很大,这样子如果我们将用户信息存在Cookie的话,一旦被窃取,那不仅网站不安全而且用户信息也没了。考虑到Cookie保存在客户端被窃取的风险较大,Session机制把服务器与浏览器的会话信息(验证信息)临时的保存在服务器上,并利用Session ID 进行客户端的识别。这样子,用户就没有权限操作服务器,可以避免非法用户窃取Session中的数据,从而保证数据的安全性。
Session可以理解为一个通信状态列表,用来跟踪用户在浏览器的行为。Session 对象存储特定用户会话所需的属性及配置信息。而且Session是基于Cookie实现的,存储在服务器端,而对应的Session ID存储在客户端的Cookie中。当浏览器关闭会或者Session超时的时候,Session也会自动失效。这样子,可以避免占用过多的服务资源。
4.2 Session的特点
👍4.2.1 Session的特点
(1)基于Cookie实现,由服务器生成并且数据存储在服务器端:Session通常使用Cookie来标识一个会话,但是存储的数据不会放置在Cookie中,只有一个关键字Session ID。Session 数据存储在服务器端,不会暴露给客户端,客户端只能拿到 Session ID,以此来区分不同用户的会话。
(2)可以存储任意类型的数据:Session 可以存储任意类型的数据,包括字符串、数字、对象等。
(3)具有独立性,会话隔离:每个用户在与服务器建立会话时,会分配一个唯一的 session ID。所有这个用户在会话期间提交的请求都会携带这个 session ID,服务器利用这个 ID 把用户的请求关联到相应的 Session,从而达到会话隔离的效果。每个Session是独立的,不会因为其他Session的变化而受到影响。
(4)具有临时性,时效性:Session 会话是临时的并且有一个过期时间,一般情况下默认为 20 分钟到 30 分钟不等。如果用户关闭浏览器或者在这个时间范围内没有发出请求,那么服务器会自动销毁这个 session,释放占用的资源。
(5)安全性高:因为 Session 数据存储在服务器端,因此它比使用客户端(例如Cookie)存储信息更安全。这是由于Session的标识符(即Session id)是由服务器生成,在有效期内随机,并且存储在服务器端,客户端无法修改。如果服务器对Session 数据进行加密和验证,可以保证 Session 数据的安全,防止被伪造和篡改。
(6)状态保持:Session可以通过将信息存储在服务器端,使得web应用能够维护用户的状态。如果用户在访问web应用时需要提交数据或者状态,这些数据和状态会被存储在Session对象中。
(7)可以跨页面访问:Session允许在同一应用程序的多个页面之间共享数据。
(8)可灵活配置,可扩展性好,适用性广,支持集群部署:Session可以根据开发需求定期清理并保存到数据库中,以实现高可扩展性,并且支持集群部署,适合大规模应用场景。Session适用于各种Web应用,如购物车、用户登录、会话状态等。
(9)存储数据多,资源占用较多:Session用于存储一次会话的多次请求的数据。因为Session 数据存储在服务器端,所以会占用服务器的一定资源,包括内存和存储空间,如果同时有大量的用户进行会话,可能会导致服务器压力较大。
👀4.2.2 Session保存的位置
- 在HTTP通信中的数据位置:
Session ID 在 HTTP请求和响应的header
中Session ID
字段中进行传输和存储。 - 存储位置:服务器端
4.3 Session的一些重要/常用属性
- Session ID(会话ID):用于唯一标识一个会话,可以是任何形式的字符串,用于区分不同用户的会话。SessionID 是连接 Cookie 和 Session 的一道桥梁。
- 创建时间(Creation Time):指示会话开始的时间,用于确定会话的有效期。
- 最后访问时间(Last Accessed Time):指示上一次访问该会话的时间,用于检测会话是否过期。
- 最大不活动时间间隔(Max Inactive Interval):一个整数,表示Session最长的空闲时间(单位秒)。Session对象在没有被访问的情况下能够保持的最长时间,超过此时间后Session将被销毁。
- 超时时间(TimeOut):设置Session对象的过期时间,单位为秒。当session超时时,它将被自动销毁。可以通过配置来设置session的过期时间,默认情况下为30分钟。
- 键集合(Keys):表示当前Session对象保存的所有属性的名称集合。可以通过调用getAttributeNames()方法来获取键的集合。
- 活动Session数目(Count):表示当前服务器上活动的Session数量。可以通过调用ServletContext对象的getActiveSession()方法来获取活动Session数目。
- 属性(Attribute):用于存储会话特定的数据,每个属性都有一个名称和一个值,并且可以通过名称进行访问。
- 生命周期(Lifecycle):指示会话从创建到销毁的整个过程,包括创建、活动、过期和销毁等阶段。
- maxSessions:设置允许同一个用户最多能够拥有的Session数量,如果超出则后续登录将被拒绝或之前的Session将会被销毁。
- isNew:判断Session是否为新创建的,如果是则返回true,否则返回false。
4.4 Session的认证流程
- 认证流程简述:对于 Session,在服务器与客户端建立连接时,服务器会为每个客户端生成唯一的Session ID,并记录这个ID和对应的用户信息和操作记录等,同时将这个ID发送到浏览器。浏览器收到会话ID之后,会在会话期间将这个ID保存在Cookie中,同时Cookie 还会记录这个SessionID 属于哪个域名。在会话期间,当浏览器再次访问时,服务器就可以根据收到的Cookie,解析出对应的Session ID,然后通过它查询Session列表中对应的Session,这样子就可以知道用户的状态和行为信息了。当关闭浏览器后,Session 会自动失效,会话的变量也会被删除。这样子,可以避免占用过多的服务资源。如果需要永久储存信息,就需要把数据存储在数据库中。
- 认证流程步骤叙述:
- 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的Session
- 请求返回时将此 Session 的唯一标识 SessionID 返回给浏览器
- 浏览器接收到服务器返回的 SessionID 后,会将此信息存入到 Cookie 中,同时 Cookie 记录此SessionID 属于哪个域名
- 当用户第二次访问服务器的时候,请求会自动把此域名下的 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。
4.5 Session的优缺点
😎4.5.1 优点
优点总结
:具有较好的安全性,灵活性(可扩展性),唯一性,便于调用,可以主动清除优点展开
:- 相对于Cookie,具有较好的安全性:相较于Cookie,Session保存在服务器端,更加安全。Session可以保存敏感数据,如用户登录信息、支付信息等,防止这些数据暴露到客户端,提高了应用程序的安全性。此外,Session ID可以防止网络钓鱼攻击和会话劫持攻击等安全问题,确保会话数据的保密性和完整性。
- 可以存储任意类型的数据:Session 可以存储任意类型的数据,包括字符串、数字、对象等。
- 较好的灵活性和可扩展性,支持集群部署:Session机制是可扩展的。通过在Session对象中保存自定义属性,可以实现更加灵活的业务需求。此外,Session可以根据开发需求定期清理并保存到数据库中,以实现高可扩展性,并且支持集群部署,适合大规模应用场景。
- 具有唯一性,独立性:每个Session是独立的,不会因为其他Session的变化而受到影响。
- 相较于JWT,具有自动清除机制:服务器会有Session回收机制,可自动删除过期Session。
- 更少的网络负载:使用会话可以避免在每个请求中重复传输相同的数据,因此减少了网络流量和服务器负载。使用Session可以避免频繁访问数据库或其他外部资源,从而减轻服务器的负担。
- 可跨页面共享信息:Session可以跨不同的页面进行信息共享,实现相同用户在多个页面中获取同样的信息。
- 状态保持,实现会话跟踪及个性化服务:Session可以在不同请求间保持数据状态,使得服务器可以识别同一个用户的连续请求,并为该用户提供个性化的服务。会话可以在用户与应用程序之间保持状态,以便在多个页面或请求之间跟踪用户信息。
- 兼容性好:因为Session是由服务器端创建和管理的,与浏览器本身无关,只要浏览器能够发送HTTP请求并支持Cookie,就可以正常使用Session。
🤢4.5.2 缺点
缺点总结
:虽然Session相较Cookie更具安全性,但Session过度依赖Cookie,并且由于存储在服务端,所以其占用服务器内存,导致性能上的损失,可能导致更多的延迟。另外Session还需要考虑负载均衡和分布式部署的问题。Session的生命周期控制难度也比较大。缺点展开
:- 过度依赖Cookie:Session ID通常以Cookie的形式存储在客户端,如果浏览器禁用Cookie,则可能导致Session失效,影响用户体验。
- 占用服务器资源,降低系统性能:使用Session需要在服务器端存储和管理会话数据,特别是当用户量较大时,会占用服务器的内存和处理能力,影响Web应用程序的性能。
- 可能导致更多的延迟:存储获取Session需要进行网络通信,而且查询Session信息可能会有数据库查询操作,可能导致更多的延迟。
- 跨进程通信困难:当Web应用程序运行在多进程环境下时,如分布式系统,不同进程之间共享Session数据时会比较困难。
- 负载均衡问题:如果应用程序使用了负载均衡技术,那么同一个用户的请求可能会被分配到不同的服务器处理,从而导致无法识别原先建立的Session,这就需要做不同服务器之间的Session同步,否则会造成Session不一致的问题。
- 分布式问题:Session是基于服务器端的,在分布式环境中,如果用户访问的是另外一台服务器,那么原先建立的Session可能无法被识别,因此需要使用其他技术来解决分布式问题,确保Session能够正确地在不同服务器之间共享和同步(多机共享Session机制),例如使用集中式Session管理服务,或者使用Cookie传递SessionID。
- 生命周期问题,生命周期控制难度大:Session默认的生命周期是会话级别,即用户关闭浏览器或Session超时后自动清除,这可能导致一些重要数据被丢失。用户需要自己管理Session的生命周期,例如手动清除过期的Session,或者将一些数据存储在其他的持久化保存器中。同时,Session生命周期的管理和控制需要考虑到多种情况,如Session的超时问题、Session的过期问题等。
- 安全问题:基于Cookie的机制容易被CSRF。此外,Session中保存的信息很重要,因此必须确保Session ID 的唯一性,避免会话劫持攻击。同时,将敏感信息存储在Session中也会增加被攻击的风险,可以考虑采用加密的方式进行存储和传输。
- 状态存储依赖于自身应用程序或第三方模块。
✍4.5.3 作用及常用场景
常用场景总结
:(1)登录状态及用户信息的管理;(2)跟踪用户行为,统计分析,个性化推荐;(3)实现数据共享,多步骤操作;(4)网站安全;(5)处理后台任务;(6)消息提醒及表单数据存储等 …展开
:- 登录状态及用户信息的管理——》用户登录认证,登录状态保持:当用户成功登录网站时,服务器会创建一个Session,保存用于标识该用户的id等信息,在用户注销或超时后清除Session。这样,在用户持续访问网站时,服务器就可以识别匹配上述信息的Session,从而知道该请求来自哪个用户。
- 跟踪用户行为(自动性)——》统计分析,个性化推荐:通过Session保存用户活动信息,比如搜索历史记录,点击次数等,可以更好地了解用户的兴趣和喜好,从而为用户提供更好的服务和推荐。
- 实现数据共享,多步骤操作:Session可以被多个页面和请求之间共享使用,如在购物车中添加多个商品时,可以使用Session来保存这些数据,并在结账时将它们全部加载出来。当用户需要通过多个步骤完成某项操作时,如注册、预订、支付等,使用Session可以在不同的页面间共享数据,并确保数据的完整性和正确性。
- 网站安全:某些网站采用Session技术来记录用户的行为。例如,如果网站监测到同一个ip地址下连续登录失败次数过多,则可能认为攻击者正在尝试用暴力破解的方式攻击该帐号,那么服务器就可以采取措施比如限制登录尝试次数等。
- 处理后台任务:某些web应用程序利用后台任务处理框架,以便在后台执行后台操作。 Session是一种适合处理此类情况的方法,可以保障任务执行的独立性和任务的执行状态。
- 消息提醒:当应用程序需要在某些页面上显示未读消息数目时,可以将未读消息数量保存在Session中,这样在用户访问页面时直接从Session中获取未读消息数量即可。
- 表单数据存储:当用户填写表单或提交数据时,使用Session来缓存表单数据,以便用户在一定时间内重新打开页面时可以继续编辑。
4.6 Session可能带来的问题
面临的挑战当然也包括Session本身的缺点,这里主要从解决的角度来讲:
- 内存占用问题 ——》解决方法:需要合理利用Session存储数据,避免存储过多的无用信息,定时清理过期Session,使用缓存等技术。
- 分布式问题 ——》解决方法:可以从存储和分布的角度分别来解决。
- 从存储的角度,可以使用集中式Session存储方案,如使用Redis或Memcached等缓存中间件存储Session信息,将Session交由这些中间件来管理。
- 从分布的角度,可以让相同 IP 的请求在负载均衡时都打到同一台机器上。以 Nginx 为例,可以配置 ip_hash 来实现。
- 安全问题 ——》解决方法:在传输过程中使用加密技术,使用HTTPS协议,在服务端对Session进行有效期和有效性等方面进行控制等。
- 生命周期问题,Session过期问题 ——》解决方法:使用定时器定时刷新Session,或者将Session的过期时间设置得更长一些,以确保Session不会过早失效。
- 负载均衡问题 ——》解决方法:可以使用集中式Session存储方案,如使用Redis或Memcached等缓存中间件存储Session信息,将Session交由这些中间件来管理;也可以使用Session复制或Session共享等技术。
- Session固定攻击问题:Session固定攻击是一种攻击方式,攻击者通过获取到攻击目标的Session ID,然后模拟该Session ID进行攻击。为了避免这种攻击,应该在Session创建时随机生成一个Session ID,不要使用容易猜测和重复的ID。
- 并发问题:当多个用户同时访问同一个资源时,容易发生并发问题,例如两个用户同时修改一个Session中的值,会造成数据不一致。为了避免这种问题,应该使用同步技术来保证数据的一致性。
4.7 Session的作用域及相关思考
4.7.1 Session的作用域
- 一般来说,每次请求不同的域都会新创建一个Session。
- 对于多标签的浏览器来说,在一个浏览器窗口中,多个标签同时访问一个页面,Session是一个。
- 对于多个浏览器窗口之间,同时或者相隔很短时间访问一个页面,Session是多个的,和浏览器的进程有关。
- 对于一个同一个浏览器窗口,直接录入URL访问同一应用的不同资源,Session是一样的。
4.7.2 当客户端关闭后,服务端不关闭,两次获取Session是同一个?
- 默认情况下不是。
- 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让Cookie持久化保存。
- 在客户端关闭后,服务端并不会立即关闭Session。但是取决于Session的实现方式和配置。
- 如果使用基于Cookie的Session,首次创建Session时会往客户端浏览器发送一个Cookie,当浏览器关闭后该Cookie会被删除。当用户再次访问站点时,浏览器并不会发送已经删除掉的Cookie,因此会重新创建一个新的Session。所以两次获取Session是不同的。
- 如果使用基于URL重写的Session实现,URL中会带有Session ID参数,服务器会基于这个Session ID来匹配已经存在的Session。当用户关闭浏览器后,打开一个新的浏览器访问时,URL中不再带有上一个Session的ID,服务器就会认为这是一次新的会话,并重新创建一个新的Session。因此,两次获取Session也是不同的。
- 如果使用了持久化Session管理技术,例如集中式缓存、数据库等存储机制,服务端的Session在客户端关闭后并不会受到影响,并且通过相同的Session ID,可以继续访问这个Session。因此两次获取Session是同一个。但需要注意的是,在设置Session的过期时间等方面需要进行合理的控制,以防Session信息长时间占用服务器资源,影响系统性能。
4.7.3 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
不是同一个,创建Session的对象分配的地址值是随机的。但是要确保数据不丢失。tomcat自动完成以下工作
- Session的钝化:在服务器正常关闭之前,将Session对象系列化到硬盘上。
- Session的活化:在服务器启动后,将Session文件转化为内存中的Session对象即可。
4.7.4 Session什么时候被销毁?失效时间?
- 服务器关闭。
- Session对象调用invalidate()。
- Session默认失效时间:30分钟,可以配置修改
5. Cookie与Session的区别及相关知识点
✨ 5.1 区别
Session更像用户信息档案表,里面包含了用户的认证信息和登录状态等信息。而Cookie就更像用户通行证
- 存储位置不同:Cookie数据是存储在客户端(浏览器)的,而Session数据则是存储在服务器端的,通常会保存在内存或者数据库中。
- 安全性: Session 比 Cookie 安全,Cookie 以明文形式存储在客户端,Session数据只保留了一个会话ID在客户端,具体数据都存放在服务端,相对来说具有较高的安全性。
- 支持的数据类型不同:Cookie 只支持存字符串数据,Session 可以存任意数据类型。
- 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能。Cookie可以设置生命周期,即在设置的时间段内一直存在于客户端,过期后才会被删除。Session则一般是在用户关闭浏览器或者长时间不操作后自动失效。
- 存储大小不同:单个Cookie通常最多支持4KB的数据存储,而Session则没有严格的限制,可以存储更大的数据量。
- 主要场景不同:对于简单而且不敏感的数据通常使用Cookie保存,如购物车信息、用户在站点的行为记录等;而对于复杂且敏感的数据使用Session保存,如用户的账号信息等。
🤔 5.2 一个思考:既然盗取了Cookie,无论是Session还是Cookie都一样会被冒充,那为什么需要Session呢?
(1)安全性:虽然Session和Cookie都可以被盗取,但Session比Cookie更安全,因为在使用Session时,Session信息是保存在服务器端的,而非客户端。当客户端请求服务器时,服务器会验证Session是否合法,只有合法的Session才会返回相应的数据。这样做的好处是在一定程度上确保了客户端请求的安全性,即使有人盗取了Session ID,也无法通过合法的请求来获取数据。
(2)设计目的:当然,如果应用程序不安全,存在漏洞或弱口令等问题,那么盗取 Cookie 的行为可能会绕过 Session 验证,从而访问到 Session 数据。尽管盗取 Cookie 可以被用于冒充身份,但 Session 本身并不是为了防范盗取 Cookie 而设计的。相反,Session更加偏向是一种数据存储方式,用于在用户与 Web 应用程序之间保持联系,目的是提供一个安全的、可靠的方式来标识和跟踪用户身份,以便对其进行访问控制和授权。
(3)Cookie只是实现Session机制的其中一种方案,并不是唯一的方法:除了使用Cookie来存储Session ID外,还可以使用其他方式来实现Session机制。比如URL 重写,隐藏表单域等。
(4)考虑客户端压力:用Session只需要在客户端保存一个ID,实际上大量数据都是保存在服务端。如果全部用Cookie,数据量大的时候客户端是没有那么多空间的。并且客户端数据量变大,网络传输的数据量也会变大。
💡 现在大多都是Session + Cookie,但是只用Session不用Cookie,或是只用Cookie,不用Session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用。
6. 下篇章笔记
通过上面的知识,我们也对Session有了一个大概的了解,所以在下篇中,笔者我将主要介绍一下主要介绍Token的相关定义及理解。
笔记链接:【前端知识】Cookie, Session,Token和JWT的发展及区别(三)
码字不易,可能当中存在某些字体错误(笔者我没有发现),如果有错误,欢迎大家指正。🤗