引言

由于 HTTP 协议是无状态的,完成操作关闭浏览器后,客户端和服务端的连接就断开了,所以我们必须要有一种机制来保证客户端和服务端之间会话的连续性,也称为认证,最常见的应用场景就是保持用户的登录态。

最基本的认证方式,就是使用 Sesson-Cookie。

30s 图解 Sesson-Cookie 认证

以保持用户登录态为例,Sesson-Cookie 认证的具体步骤如下:

1)客户端(浏览器): 向服务器发送登录信息(用户名和密码)来请求登录校验;

2)服务端: 验证登录信息,验证通过后服务器(比如 Tomcat)会自动为此次请求开辟一块内存空间(一个 Session 对象),可以手动将用户信息(比如登录保持时间是否过期)存在 Session 对象中。然后,服务器会自动为这个 Sesson 对象生成一个唯一的标识 sessionID ,并在 HTTP 响应头(Header)的 Set-Cookie:JSESSIONID=XXXXXXX 中设置这个 seesionID

所以说,Session 的实现是依赖于 Cookie 的

3)客户端: 收到服务端的响应后会解析响应头,从而根据 set-CookiesessonId 保存在本地 Cookie 中,这样,客户端(浏览器)在下次 HTTP 请求时请求头会自动附上该域名下的 Cookie 信息;

4)服务端: 接收客户端请求时会去解析请求头 Cookie 中的 sessonId,然后根据这个 sessonId 去找 Sesson 对象,从而获取到用户信息;

可以通过拦截器在每次请求前尝试获取 Sesson 对象:Session 存活期间,我们认为客户端一直处于活跃状态(用户处于登录态),一旦 Session 超期过时,那么就可以认为客户端已经停止和服务器进行交互了(用户退出登录)。

如果遇到禁用 Cookie 的情况,一般的做法就是把这个 sessionID 放到 URL 参数中。这也是经常在面试中会被问到的问题。

可能会有同学问为啥不直接把数据全部存在 Cookie 中,还整个 Session 出来然后把 sessionID 存在 Cookie 中的?

  1. Cookie 长度的限制:首先,最基本的,Cookie 是有长度限制的,这限制了它能存储的数据的长度
  2. 性能影响:Cookie 确实和 Session 一样可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些 Cookie,那如果 Cookie 中存储的数据比较多的话,这无疑增加了客户端与服务端之间的数据传输量,增加了服务器的压力。
  3. 安全性:Session 数据其实是属于服务端的数据,而 Cookie 属于客户端,把本应在 Session 中存储的数据放到客户端 Cookie,使得服务端数据延伸到了外部网络及客户端,显然是存在安全性上的问题的。当然我们可以对这些数据做加密,不过从技术来讲物理上不接触才是最安全的。

附加阅读

Sesson-Cookie 认证伪代码

登录:

拦截器:每次请求前去找 Sesson 对象,从而获取到用户信息

可以看出来,在一次会话当中,两个请求获取到的 Session 对象实际上是同一个对象。

上面已经提到,服务器是根据 cookie 中的 sessionID 来找到 Session 对象的,但以上代码中我们只是手动将用户数据设置到了 Session 中,并没有出现任何关于 Cookie 的代码(将 SessionId 设置到 Cookie 中)

很明显,这些肯定都是服务器(比如 Tomcat)自动完成的了。在第一次获取 Session 即调用 request.getSession() 的时候,服务器会自动创建一个 Session 对象(Session 是一个集合,并且是一个 Map 集合),并且存入服务器的 Session 集合中以 SessionId 为标识键,也就是说根据 SessionId 即可取到对应 Session 的引用。同时也会创建一个键名为 JSESSIONID 的 Cookie 并且返回给浏览器,该 Cookie 的值即为 SessionId。

这个存储着 SessionId 的 Cookie 会跟着请求上传到服务器,所以说,在同一会话当中,不管哪个请求拿到的都是同一个 Session 对象。

Sesson-Cookie 认证的缺点与解决方案

这种机制在单体应用时代应用非常广泛,但是,随着分布式时代的到来,Session 的缺点也逐渐暴露出来。

举个例子,比如我们有多个服务器,客户端 1 向服务器发送了一个请求,由于负载均衡的存在,该请求被转发给了服务器 A,于是服务器 A 创建并存储了这个 Session

紧接着,客户端 1 又向服务器发送了一个请求,但是这一次请求被负载均衡给了服务器 B,而服务器 B 这时候是没有存储服务器 A 的 Session 的,这就导致 Session 的失效。

明明用户在上一个界面还是登录的,跳到下一个界面就退出登录了,这显然不合理。

当然了,对此的解决方法其实也有很多种,其实就是如何解决 Session 在多个服务器之间的共享问题

  1. Sesson Replication
  2. Sesson Sticky
  3. Sesson 数据集中存储

Session Replication

这个是最容易想到的,既然服务器 B 没有服务器 A 存储的 Session,那各个服务器之间同步一下 Session 数据不就完了。

这种方案存在的问题也是显而易见的:

  1. 同步 Session 数据带来了额外的网络带宽开销。只要 Session 数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大。

  2. 每台Web服务器都要保存所有 Session 数据,如果整个集群的 Session 数据很多(比如很多人同时访问网站的情况),每台服务器用于保存 Session 数据的内存占用会非常严重。

Session Sticky

从名称也能看出来,Sticky,即让负载均衡器能够根据每次的请求的会话标识来进行请求的转发,保证一个会话中的每次请求都能落到同一台服务器上面

存在问题的:

  1. 如果某台服务器宕机或者重启了,那么它上面存储的 Session 数据就丢失了,用户就需要重新进行登陆。

  2. 负载均衡器变为一个有状态的节点,因为他需要保存 Session 到具体服务器的映射,和之前无状态的节点相比,内存消耗会更大,容灾方面会更麻烦。

Session 数据集中存储

将每个服务器的 Session 数据都集中存到外部介质比如 Redis 或者 MySQL 中去,然后所有的服务器都从这个外部介质中拿 Session 就行了

存在的问题也很显然:

  • 过度依赖外部存储,如果集中存储 Session 的外部存储机器出问题了,就会直接影响到我们的应用

小伙伴们大家好呀,本文首发于公众号@飞天小牛肉,阿里云 & InfoQ 签约作者,分享大厂面试原创高质量题解、原创技术干货和成长经验。回复『春秋招』我拉你进求职吹水交流群,回复『Echo』免费获取社区项目手把手教程

如何用 30s 给面试官讲清楚什么是 Session-Cookie 认证的更多相关文章

  1. 我是如何用 ThreadLocal 虐面试官的?

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. Thr ...

  2. 如何用json 与jsonp 的区别去回答你的面试官?

    常常 有面试官这样问我们,虽然用过无数次,但是回答不上岂不是尴尬,那我们浅析一下它们的区别? 1. json JSON是一种基于文本的数据交换格式,用于描述复杂的数据,举个例子: var nax=[ ...

  3. 引用面试官文章 :如何准备Java初级和高级的技术面试

    本人最近几年一直在做java后端方面的技术面试官,而在最近两周,又密集了面试了一些java初级和高级开发的候选人,在面试过程中,我自认为比较慎重,遇到问题回答不好的候选人,我总会再三从不同方面提问,只 ...

  4. java面试官如何面试别人

                                                                                      java面试官如何面试别人(一) j ...

  5. 8年经验面试官详解 Java 面试秘诀

      作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三 ...

  6. 一个资深java面试官的“面试心得”

    在公司当技术面试官几年间,从应届生到工作十几年的应聘者都遇到过.先表达一下我自己对面试的观点: 1.笔试.面试去评价一个人肯定是不够准确的,了解一个人最准确的方式就是“路遥知马力,日久见人心”.通过一 ...

  7. iOS开发,这样写简历才能让大厂面试官看重你!

    前言: 对于职场来说,简历就如同门面.若是没想好,出了差错,耽误些时日倒不打紧,便是这简历入不了HR的眼,费力伤神还不能觅得好去处,这数年来勤学苦练的大好光阴,岂不辜负? 简历,简而有力.是对一个人工 ...

  8. (转)史上最全 40 道 Dubbo 面试题及答案,看完碾压面试官!

    背景:因为自己的简历写了dubbo,面试时候经常被问到.实际自己对dubbo的认识只停留在使用阶段,所以有必要好好补充下基础的理论知识. https://zhuanlan.zhihu.com/p/45 ...

  9. 面试官问我,使用Dubbo有没有遇到一些坑?我笑了。

    前言 17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之前的粉丝,这里不过多介绍. 根据我的面试经验 ...

  10. 面试官问我,使用Dubbo有没有遇到一些坑?我笑了

    17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之前的粉丝,这里不过多介绍. 根据我的面试经验而言, ...

随机推荐

  1. 4.ElasticSearch系列之基本概念

    1. 文档 ElasticSearch是面向文档的,文档是所有可搜索数据的最小单位 文档会被序列化成JSON格式,保存在ES中 每个文档都有一个unique ID #查看前10条文档,了解文档格式 P ...

  2. FJOI2007轮状病毒 行列式递推详细证明

    题目链接 题目给了你一个奇怪的图,让你求它的生成树个数. 开始写了一个矩阵树: #include<cstdio> #include<cstdlib> #include<c ...

  3. HTML+CSS基础知识(5)相对定位、绝对定位、固定定位

    文章目录 1.相对定位 1.1 代码 1.2 测试结果 2.绝对定位 2.1 代码 2.2 测试 3.固定定位 3.1 代码 3.2 测试结果 1.相对定位 1.1 代码 <!DOCTYPE h ...

  4. python爬虫下载小说

    1. from urllib.request import urlopen from urllib import request from bs4 import BeautifulSoup from ...

  5. 14.-F对象和Q对象

    一.F对象 一个F对象代表数据库中某条记录的字段的信息 作用 通常是对数据库中的字段值在不获取的情况下进行操作 用于属性(字段)之间的比较   语法: from django.db.models im ...

  6. 【MySQL】01_运算符、函数

    运算符 运算符是保留字或主要用于 SQL 语句的 WHERE 子句 中的字符,用于执行操作,例如:比较和算术运算. 这些运算符用于指定 SQL 语句中的条件,并用作语句中多个条件的连词. 常见运算符有 ...

  7. centos7离线安装PHP7

    环境 centos7.9 PHP7.4.30 准备工作 在编译PHP时会提示一些包版本不够或者缺少某些包,一般选择yum来安装缺少的包,但因为是离线安装,所以可以手动配置本地yum源.先看一下系统版本 ...

  8. 原生Ajax处理文件流

    在通过Ajax处理请求时,可能会遇到需要下载文件的情况,这里简要的说明下处理方法. let downloadFile = document.getElementById("downloadI ...

  9. 1.python基础使用

    1.git简介 git是一个免费的开源的分布式版本控制系统,可以快速高效的处理从小型到大型项目的所有事务 在实际工作中可以保留项目的所有版本,可以快速的实现版本的回滚和修改 git整体可以分为4个区域 ...

  10. 《Design by Contract for Embedded Software》 翻译

    原文: Design by Contract for Embedded Software (state-machine.com) Design by Contract is the single mo ...