了解cookie
Cookie是在Web服务器和Web浏览器之间传递的一小段数据,用于在浏览器和服务器之间维持会话状态。保存session(通过身份验证后服务端为用户创建一个会话标识符)
想象一下你去一家咖啡店。你点了一杯咖啡,并且收银员给你一张小纸条,上面写着你的订单号码。你拿着这张小纸条,然后坐下来等待你的咖啡。当咖啡准备好后,服务员会根据你手上的订单号码找到你,并把咖啡送到你的桌子上。
在这个例子中,订单号码就像是一个cookie。它是一个小的标识符,帮助咖啡店识别你的订单。当你拿着订单号码坐下时,咖啡店就知道你是谁,并准备好你的咖啡。这样,无论你是在咖啡店的哪个位置,他们都可以准确地为你提供服务。
那么cookie可以用来做什么呢?我们从三个主要的功能来讲解它。
- 身份验证:Cookie在身份验证方面发挥重要作用。当你登录一个网站时,网站通常会生成一个用于身份验证的cookie,并将其存储在你的浏览器中。这个cookie包含一个加密的唯一标识符,用于识别你的身份。在之后的请求中,浏览器会将该cookie发送给服务器,以便服务器确认你的身份,并允许你访问需要登录的受限资源。
- 会话管理:另一个重要的作用是在网站的会话管理中。当你与网站进行交互时,服务器会为你创建一个会话,并生成一个唯一的会话标识符(也就是session)。这个标识符通常以cookie的形式发送给你的浏览器。浏览器会在后续的请求中将该cookie发送回服务器,以便服务器识别你的会话,并在会话期间跟踪你的状态和数据。这使得网站能够在多个页面之间保持用户的连贯性,例如保存购物车中的商品或记录浏览历史。
- 持久登录:有时候,网站提供了"记住我"或"保持登录状态"的选项,这需要使用持久登录(也称为"持久性会话")来实现。当你选择记住登录状态时,网站会在你的浏览器中设置一个持久性的cookie。这个cookie通常具有较长的过期时间,甚至可以保持几天或几周。当你关闭浏览器或重新启动计算机后,这个cookie仍然存在,使得你在下次访问网站时无需重新登录。持久登录提供了方便性,但也需要谨慎使用,以确保安全性和隐私保护。
了解完cookie是什么,有什么作用,让我们展开今天的主题!
问题引入
比如我现在有两个域名:
思考一个假设我的cookie是在A.com上,如果B.com想访问A.com的cookie能访问到吗?
答案是不能访问到的,因为我们的cookie是种在A.com的域名上,即使B.com通过前台发送请求给后台,因为B.com向后台发送请求时是不会带上A.com这个cookie的。
因此如果想要共享cookie,可以种一个更高层的公共域名,比如xhl.com,那么在子层的域名就能共享到cookie,A.com和B.com这两个域名就能具有同一个cookie。
为什么服务器A登录后,请求发送给服务器B,不认识该用户呢?
用户在A 登录,session(用户登录的信息)是存在A上的,当用户去请求B服务器的时候,由于没有存储用户信息,所以不认识。
想象一下,你正在参加一个大型音乐节,音乐节的入口处有一个安检站。你来到安检站,安检员检查你的票和身份,并在你的手腕上贴上一个标签,以表示你已经通过了安检。
现在,你已经通过了安检,并且在音乐节内自由地漫步。在演出期间,你想去音乐节场地外的一个小吃摊购买一些食物。然而,当你到达小吃摊时,他们并不知道你已经通过了安检,并且没有给你贴上标签。因此,他们无法确认你是否已经接受了安检,无法提供给你服务。
如何实现共享数据存储?
实现共享数据存储有多种方法,下面我将介绍几种常见的方法,并列出它们的优缺点:
- 数据库共享:使用共享数据库是一种常见的实现方式。多个服务器可以连接到同一个数据库,并共享数据。这种方法的优点是数据一致性高,所有服务器都可以读取和写入相同的数据。然而,数据库的性能可能成为瓶颈,特别是在高并发的情况下,需要谨慎设计和调优。
- 分布式缓存:使用分布式缓存系统(例如Redis或Memcached)来存储共享数据是另一种常见的方法。多个服务器可以通过连接到同一个分布式缓存来读取和写入数据。这种方法的优点是缓存系统通常具有快速的读写性能,并且可以水平扩展。然而,需要注意的是,缓存系统通常是基于内存的,因此对于大量的数据或需要持久化的数据,需要谨慎处理。
- 分布式文件系统:使用分布式文件系统(例如Hadoop的HDFS或GlusterFS)可以实现共享数据存储。多个服务器可以连接到同一个文件系统,并在其中读取和写入数据。这种方法的优点是文件系统通常具有高容量和高可靠性,并且支持并发访问。然而,文件系统的一致性可能需要额外的管理和协调。
- 分布式数据库:使用分布式数据库系统(例如Cassandra、MongoDB或Spanner)可以实现共享数据存储。这种方法将数据分散存储在多个节点上,并提供数据的一致性和可用性。优点包括横向扩展和高可用性,但需要考虑数据分片、复制和一致性的管理。
具体来说:
- redis (基于内存的 K / V 数据库)
因为用户信息读取/是否登录的判断极其频繁,Redis基于内存,读写性能很高,简单的数据单机qps 5w-10w - QPS:意思是每秒查询率,指一台服务器每秒能够响应的查询次数,用于衡定特定的查询服务器在规定的时间内所处理流量多少,主要针对专门用于查询的服务器的性能指标。
- MySQL
文件服务器ceph
使用redis实现session共享
基本原理
使用Redis实现会话(Session)共享的原理是将会话数据存储在Redis数据库中,从而使多个服务器能够共享和访问相同的会话数据。下面是使用Redis实现会话共享的基本原理:
- 配置Redis:首先,需要在多个服务器上安装和配置Redis数据库。确保所有服务器都能够连接到相同的Redis实例。
生成会话ID:当用户在其中一个服务器上登录时,会为其生成一个唯一的会话ID。这个会话ID可以是一个随机生成的字符串或其他唯一标识符。 - 存储会话数据:将用户的会话数据存储在Redis中。可以使用Redis的字符串数据结构来存储会话数据,其中会话ID作为键,会话数据作为值。可以使用Redis的SET或HMSET命令来设置会话数据。
- 将会话ID发送给客户端:将生成的会话ID发送给客户端,通常通过将会话ID存储在cookie中。客户端的浏览器会在后续的请求中将该cookie发送回服务器。
- 从Redis中检索会话数据:当客户端发送请求到其他服务器时,服务器会从Redis中检索会话数据。通过读取请求中的会话ID,服务器可以使用Redis的GET或HMGET命令从Redis中获取存储的会话数据。
处理会话数据:服务器可以使用获取到的会话数据来验证用户身份、获取用户配置或执行其他与会话相关的操作。
实现步骤
- 下载redis ,官网:https://redis.io/
- 下载redis管理工具quick redis:https://quick123.net/
- 引入redis,在springboot中操作redis
xml
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.4</version>
</dependency>
- 引入 spring-session 和 redis 的整合,使得自动将 session 存储到 redis 中:
xml
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.6.3</version>
</dependency>
- 修改 spring-session 存储配置 spring.session.store-type,默认是none,表示存储在单台服务器,store-type: redis,表示从 redis 读写 session。
session 失效时间
xml
session:
timeout: 86400
store-type: redis
然后我们就可以写一个单元测试,写一个@Resource注解引入redis并操作了。