详解 Session 和 Cookie

前提

51 也有个文章跟我一样,是我自己投的稿哈

 

为什么要用Session和Cookie?

简单一句话,因为 Session 和 Cookie 可以记录用户状态信息

嘶..这到底啥意思呢?

 

背景一:动态网页的出现

什么是静态网页

  • 含义:一个网页的内容是 HTML 代码编写的,文字、图片等内容均可通过HTML代码指定了
  • 优势:加载速度快,编写简单
  • 劣势:可维护性差,扩展性差,不能根据URL显示不同的内容;例如:在 URL 传入一个name参数想在网页上显示,静态网页是无法做到的
  • 总结:弊大于利

 

动态网页的诞生

  • 动态网页可以动态解析 URL 中参数的变化,关联数据库并动态呈现不同的页面内容,非常灵活多变
  • 现在遇到的大多数网站都是动态网站,不再是一个简单的 HTML 页面,可能由 JSP、PHP、Python 等语言编写的,功能比静态网页强大和丰富太多

场景:一个需要登录的动态网站,在登录后需要保持登录状态,以便后续访问网站其他网页;那么我们要通过什么来保存这个登录态呢?

 

背景二:HTTP是无状态协议

HTTP无状态是指?

HTTP协议对事务处理是没有记忆能力,也就是说服务器不知道客户端是什么状态

 

这是什么意思呢?

  • 当我们向服务器发送请求后,服务器解析处理请求,然后返回响应,服务器负责完成这个过程(也是一个事务)
  • 而这个过程是独立的,服务器不会记录前后状态的变化,也就是缺少状态记录

 

无状态导致的后果?

  • 意味着后续发出的请求需要处理前面请求的响应,则必须重传
  • 这也导致需要额外传递一些前面的重复请求,才能获取后续响应
  • 但为了保持前后状态,我们也不能将前面的请求全部重传一次,这太浪费资源了
  • 就好像如果一个网站每次发出一个请求前都要先发出一次登录请求,这无疑大大增加了资源浪费程度

 

举栗子:百度

网站常常需要记录访问者的一些基本信息,例如:用户是否登录、用户登录名称、密码、用户在 Web 站点购物的方式或用户访问该站点的次数

举个例子,用户在没有登录 baidu 时,此时用户的身份是游客,baidu 首页的界面如下图所示:

 

当用户登录 baidu 页面后,此时用户的身份是已登录用户,可以看到页面的右上角显示了用户的名称,如下图所示

  • 可以看出,baidu 服务端能够辨别用户的身份,根据用户是否登录显示不同的内容
  • 如果用户的身份是游客,则显示登录
  • 如果是已登录用户,则显示用户的名称

 

Seesion和Cookie的诞生

上图可以看出,Session 和 Cookie 在一个网站中各自发挥的作用

 

使用 Cookie 辨别用户的身份

  • 网站为了辨别用户身份、进行会话跟踪需要把一些数据(例如:登录状态、用户名称)储存在用户本地终端上,这些数据被称为 Cookie
  • 以登录 baidu 为例子,用户在没有登录 baidu 时,访问的网页 URL 是 https://www.baidu.com
  • 在登录 baidu 后,访问的网页 URL 仍然是 https://www.baidu.com
  • 访问的页面 URL 相同,但是这两次访问呈现的结果不相同,登录前没有显示用户名,登录后显示了用户名  

 

那服务端是怎么区分两个请求呢?

  1. 用户登录 baidu
  2. baidu 服务端会生成一个用户 ID
  3. baidu 服务端将这个用户 ID 发送给浏览器
  4. 浏览器收到这个用户 ID 后,会将这个用户 ID 保存在用户本地终端
  5. 浏览器再次访问 baidu 站点时,浏览器会将保存在本地的用户 ID 发给 baidu 服务端
  6. 服务端收到浏览器发送的用户 ID 后,就知道此次请求来自于一个已登录的用户

以上交互过程中,保存在客户端的用户ID 就是 Cookie 

 

实际场景

  1. 当我们登录之后,服务端就会创建一个属于当前用户的 Session,里面保存的就是当前用户的信息;
  2. 然后浏览器会根据服务器的响应头中 Set-Cookie 字段生成相关 Cookie,相当于一个用户凭证
  3. 只需要在下次请求时携带这些 Cookie,服务器就能通过 Cookie 来判断用户是否是登录状态,然后返回对应的响应

不好理解?继续往下看!

 

生动形象理解Cookie和Session的关系

  1. Session 是保存在服务器端,Cookie 是保存在客户端
  2. 每次用户访问网站的时候,相当于去串门
  3. 用户带着 cookie 去服务器家,当当当敲门
  4. 服务器问是谁啊
  5. 用户:是我(cookie)啊
  6. 服务器:让我来确认一下(session确认)
  7. 服务器确认完毕后,放用户进门

 

实际网站登录请求的响应头

  1. 这是一个网站登录之后返回的响应头,可以看到服务器要求浏览器设置的 Cookies 有好几个;这就是 Cookies 的来源,而 token 一般会作为用户的唯一凭证【登录成功,响应头set-cookies,浏览器设置Cookies】
  2. 当浏览器下一次再请求该网站时,浏览器会把这些Cookies放到请求头一起提交到服务器;而Cookies携带了SessionID信息(x-token)【再次请求,带上 cookies,包含 SessionID】
  3. 服务器通过 SessionID 即可找到对应的用户 Session 信息,然后判断该用户的登录状态【服务器根据 SessionID 获取用户信息】
  4. 如果 Session 中某些设置登录状态的变量是有效期内的,证明用户处于登录状态【Session 有效,用户已登录】
  5. 此时服务器就会返回需要登录之后才可以查看的网页内容,浏览器再进行解析便可以看到了【返回请求响应内容】
  6. 当 Cookie 无效或者 Session 已过期后,我们再访问网站就需要重新登录了【Cookie 无效,Session 过期,需要再次登录】

 

使用 Cookie、Session 最简单的流程图

 

Session和Cookie在登录功能上的协同关系

 

Session

  • 是在服务端保存的一个数据结构
  • 用来存储用户的信息(比如登录状态、用户名称)
  • Session 数据可以保存在内存(比如 Redis)、文件或数据库中
  • Session 有一个唯一标识 SessionID,会对应一个用户
  • 在服务端通过 SessionID 会找到特定的一个用户数据

 

小栗子

  • 假设有 2 个用户:用户 A 和用户 B;
  • 在服务端存在 2 个 Session,用于存储用户 A 和用户 B 的数据

在服务端通过 SessionID 查找 Session 的过程如下

  1. 每一个 Session 有一个唯一标识,用户A 的 SessionID 为0,用户B 的 SessionID 为1
  2. 用户访问网站时,会把自己的 SessionID 作为 Cookie 发送给服务端
  3. 服务端根据请求中的 SessionID 来查找对应的 Session

 

实际场景

  • 在Web中,Session对象用来存储特定用户 Session 所需的属性和配置信息,这样用户在应用程序的Web页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户 Session 中存在下去
  • 当用户请求网页时,该用户还没有 Session,则Web服务器将自动创建一个 Session 对象
  • 当 Session 过期或被放弃后,服务器将终止该 Session

 

Cookie

某些网站为了辨别用户身份,进行 Session 跟踪而存储在用户本地终端上的数据

 

会话Cookie和持久Cookie

会话Cookie

可以将打开浏览器-关闭浏览器理解成一个会话,会话Cookie的有效期仅在浏览器打开期间;而会话Cookie是存在浏览器内存里的

实际场景:涉及钱,涉及利益、机密内容的网站一般都是会话Cookie,如企业邮箱等

 

持久Cookie

持久Cookie是存在客户端本地硬盘中,不受浏览器关闭影响,下次再次访问该网站时还能继续使用,用于长久保持用户登录状态

实际场景:可以勾选【自动登录】、【30天内自动登录】的网站用的就是持久Cookie

 

持久Cookie发出请求时,客户端与服务器之间的时序图

 

浏览器中看Cookie

  • Name:Cookie 的名称。Cookie 一旦创建,名称便不可更改
  • Value:Cookie 的值。如果值为 Unicode 字符,需要为字符编码。如果值为二进制数据,则需要使用 BASE64 编码。
  • Domain:Cookie注入的域名,如.baidu.com下的Cookie,只要Host以.baidu.com结尾的域名都能访问该Cookie
  • Path:允许使用该Cookie的路径,一般都为 / 
  • Expires/Max-Age:Cookie失效时间,若没有指定失效时间则默认当浏览器关闭时Cookie失效
  • Size:Cookie大小
  • HttpOnly:若True,则不允许脚本来访问该Cookie(如:JS)
  • Secure:Cookie是否仅被使用安全协议传输,默认为False

 

敲重点的知识点

“只要关闭浏览器,Session 就消失了” —— 错!

实际场景:去健身房办理的会员卡,除非你自己要求销卡,不然店家不会随意销掉你的卡

所以,对于 Session 也是一样的,登录的时候服务器帮你生成了一个 Session,是不会轻易删除你的 Session,除非你自己提出要删除 或 Session有效期过了;而一般我们会通过【退出】来删除触发服务器删除 Session

 

当我们关闭浏览器时,浏览器是不会通知服务器说它要关闭,所以服务器根本不知道浏览器已关闭,造成这样的误解全都是因为:

  1. 一般情况下,网站都会用 Cookie 来保存 SessionID 信息的
  2. 当你的 Cookie 是会话 Cookie 时,关闭浏览器 Cookie 就会消失
  3. 再次打开网站也找不回之前的那个 Cookie 对应的 SessionID
  4. 所以无法通过原来的 SessionID 在服务器查找对应用户的登录状态,只能重新登录生成新的 Cookie 来记录新的 SessionID

 

如何解决?

就是将 Cookie 设置为持久 Cookie,当你关闭浏览器再打开网站时,还是能从本地读取到 Cookie,从而获取到原来的 SessionID,以此来保持登录状态

 

另外

而恰恰因为关闭浏览器并不会让服务器主动删除 Session,为了避免服务器的资源浪费,一般服务器都会为每个 Session 设置一个失效时间,当 Session 的时间超过失效时间时,服务器会自动删除 Session

 

posted @ 2020-09-03 09:07  小菠萝测试笔记  阅读(2928)  评论(3编辑  收藏  举报