引言

由于 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. vlunhub靶场之EMPIRE: LUPINONE

    准备: 攻击机:虚拟机kali.本机win10. 靶机:EMPIRE: LUPINONE,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub ...

  2. 齐博x2是什么?

    齐博x2是什么? 齐博x2是齐博x1的延申版本. 对小程序全方位加强

  3. go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务

    0.索引 go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务 0.1源码地址 https://github.com/liuyuede123/go-zero ...

  4. 使用LEFT JOIN 统计左右存在的数据

    最近做了一个数据模块的统计,统计企业收款.发票相关的数据,开始统计是比较简单,后面再拆分账套统计就有点小复杂,本文做一个简单的记录. 需求 企业表 企业表t_company有如下字段:标识id.企业名 ...

  5. Redis 常见问题-缓存穿透

    问题描述: * 针对 DB 中不存在的数据源,每次请求缓存和数据库都不存在 造成后果: * 应用服务器压力变大 * Redis 命中率大幅度降低 * `数据库压力巨增甚至 down 掉`* 该现象对于 ...

  6. 8.DRF请求响应和api_view

    一.请求对象(Request objects)   DRF引入了一个扩展Django常规HttpRequest对象的Request对象,并提供了更灵活的请求解析能力 Request对象的核心功能是re ...

  7. @RequestBody 注解问题

    /**         * 不管你是get 请求 还是 post 请求  只要你的参数名称叫做abc          * 这里的abc 必须和 postman里面的key 一样          * ...

  8. webpack -- element-ui 的按需引入

    简单说明原理: 使用babel-plugin-component实现按需引入.打包.将webpack配置成多入口,保证最终打包的目录结构符合babel-plugin-component插件的要求,实现 ...

  9. 嵌入式-C语言基础:联合体和共用体的概念

    有时候同一块内存空间存放类型不同,不同类型的变量共享一块空间. 结构体和共用体的区别: (1)结构体元素有各自单独空间,共用体元素共享空间,空间大小由最大类型确定. (2)结构体元素互不影响共用体赋值 ...

  10. 2022-11-08 Acwing每日一题

    本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...