cookie和session都是常用的客户端和服务端存储和跟踪用户信息的机制,主要还是应用于Web开发中。
当用户进行登录的适合,服务端会将登录态信息(文本信息,一般是个json数据)返回给客户端,客户端进行存储这些登录态信息,当下次进行请求服务端接口的时候,会进行携带这些登录态信息。Cookie会被存储到请求标头中,是一个键值对信息文本,多个键值对使用;进行区分。
1.浏览器进行登录的时候,服务器进行创建cookie,将携带登录态信息的cookie返回给客户端
2.客户端接收到cookie之后,进行存储cookie(存储位置一般是浏览器所在设备的内存或者磁盘里)
3.浏览器再次进行请求服务端的时候,会进行携带cookie
4.读取cookie,服务端进行接收到浏览器请求的时候,会进行读取请求头中的cookie信息
5.校验cookie中的登录态信息是否正确
6.返回请求接口的数据信息
存储限制:Cookie进行存储信息的时候大小有限制,一般在4KB左右。
生命周期:Cookie可以进行设置过期时间,过期后会被自动删除,如果没有进行设置过期时间,Cookie在浏览器关闭时失效,临时cookie存储在内存中,持久cookie存储在硬盘中。
作用域:Cookie不可域名,但是可以跨端口和路径
安全性:由于Cookie存储在客户端,因此它可能被用户或恶意软件读取和修改。敏感信息不应该直接存储在Cookie中,或者应该使用加密来提高安全性。
Session时服务端的一种存储机制,用来进行跟踪用户的状态,Session在用户与服务器简历连接后创建,并在用户退出或者Session超时后销毁,并且Session默认是依赖于Cookie的(Session可以不依赖于Cookie)。
默认使用session实现登录的时候,存储到本地服务器中,借助cookie进行协同保存登录态。
也可以进行借助redis实现session的存储,如果存储在redis中,session一般是这样进行存储的。
session是存储在服务器中的,当服务器如果宕机或者重启的话,原本在服务器生成的session都会消失,如果基于本地服务器进行实现session,此时的cookie请求过去的sessionID就会失效,但是存储在redis中的session依然会被保存下去,所以存储在redis中的sessionID不会因为服务器的宕机而导致失效。
我们先来基于Cookie存储到服务端的Session的工作原理:
我们再来看一下存储到Redis的Session的工作原理
如果是借助本地服务器进行实现:
1.用户第一次进行登录的时候,服务器生成SessionID和存储登录态
2.服务器响应回去SessionID,客户端进行存储到Cookie里(当然也可以存储到其他地方)
3.用户进行登录,携带Cookie中的SessionID
4.服务端根据SessionID去服务器中查询登录态信息
如果是借助Redis进行实现,就是将SessionID对应的登录态数据,存储到了Redis中,这样可以进行实现分布式登录。
存储限制:Session是没有存储容量限制的,因为Cookie中仅需要存储一个占用极小的SessionID,Session中存储的登录态信息一般进行存储在服务器/Redis中,所以只要硬件足够强,就没有什么存储限制。
生命周期:Session的生命周期通常取决于会话的持续时间,可以在用户关闭浏览器后依然保持,指导Session超时或者被显式销毁。
安全性:由于Session存储在服务端,因此相比于Cookie更加安全,但是Session的安全性,也以来于SessionID的安全性。
识别方式:Session通过通过SessionID进行识别,这个ID在用户首次访问服务器时生成,并存储在Cookie中发送到客户端,或者通过URL传递。
存储位置:Cookie存储在客户端浏览器,Session存储在服务端
存储大小:Cookie大小受限,Session理论上并没有大小限制
安全性:Session比Cookie更加安全一些
我们由客户端为什么知道去服务端取哪个Session来看这个话题
当用户进行请求的时候,服务端会查看生成的SessionID是否在Cookie中进行存储,根据SessionID去服务端查找SessionID对应的登录态信息(KV存储),如果cookie中没有这个信息,服务端就会创建一个Session信息并返回给客户端进行存储(任何一个请求都会 => 前提是服务端选择了session校验登录态这种机制),等下次进行再去访问的时候根据这个SessionID去查询登录态信息,如果存在登录态信息就可以查询,没有进行设置登录态信息就会查询不到登录态信息。
但是如果我们关闭了cookie,就无法借助这种思路进行查询信息,要么不选择这种方式,要么进行选择配置其他方式进行存储SessionID
当我们在服务端设置了Session的过期时间,服务端会双向在服务端本地和客户端都会设置过期时间(给Cookie进行设置时间)
如果清除了Cookie缓存,服务端接收不到请求头中的SessionID信息,就会重新生成SessionID,并进行使用新的SessionID,但是旧的Session并不会在服务端消失,因为清理浏览器的缓存并不会进行影响到服务端。
如果我们浏览器存储的SessionID在服务端对应的Session已经过期了,服务端就会重新创建一个SessionID,并不会沿用以前的SessionID了。
服务端重启后或者Redis进行清理了Session缓存,Session数据都会消失,这样所有客户端的SessionID都会失效了,在下一次访问服务端的时候需要重新进行创建Session。
Cookie是依赖于浏览器的,但是如果我们的客户端不是浏览器,而是其他例如安卓等,这些客户端是没有cookie的,我们需要在请求头中自己封装一个Cookie,并将SessionID给携带过去,就可以解决这个问题了。
sessionid是一个会话的key,浏览器第一次访问服务器会在服务器端生成一个session,有一个sessionid和它对应。tomcat生成的sessionid叫做JSESSIONID,如果我们进行使用的是spring-session-data-redis将Session数据存储到Redis中,那这个类库帮我们进行生成的key是SESSIONID。
session在访问tomcat服务器HttpServletRequest的getSession(true)的时候创建,tomcat的ManagerBase类提供创建sessionid的方法:随机数+时间+jvmid;采用这种方式,可以减少SESSIONID冲突的可能性,保证数据安全等。
存储在服务器的内存中,tomcat的StandardManager类将session存储在内存中,也可以持久化到file,数据库,memcache,redis等。客户端只保存sessionid到cookie中,而不会保存session,session销毁只能通过invalidate或超时,关掉浏览器并不会关闭session。
那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。
删除可以使用:超时机制,程序调用HttpSessioninvalidate(),程序关闭。
可以看我的这篇文章:登录注册和登录状态维护场景总结(一)-CSDN博客
这周更新计划:登陆注册和登录状态维护场景(二),深入理解JAVA的String类,加密的艺术(一)。