登陆验证发展史(cookie认证->session认证->token认证->JWT,单系统登陆->多系统单点登陆)

登陆验证发展史有两条主线。在服务部署方式层面,早期的Web服务系统简单一般都是单系统,登陆的话就登陆这一个系统就好了,随着系统复杂性越来越高,一个大的系统往往由很多子系统组成,用户使用这个大系统时不可能一个一个地单独去登陆每个小系统,理想的是只要登陆上了这个大系统或者其中的一个小系统,其它所有小系统都不需要再输密码什么的登陆了,直接访问,所以登陆验证就从单系统登陆演进为多系统的单点登陆。而在验证方式层面,经历了cookie认证->session认证->token认证->JWT的发展史。

以单系统登录举例,先从验证方式层面去看:

1.cookie验证

简单介绍一下cookie,cookie其实可以理解成存储在浏览器上的一种数据,里面的数据格式是key-value键值对,数据本质上是保存在终端某个本地文件夹内。cookie不能跨域,浏览器在访问某网站地址时,如果该网址的域有cookie保存在浏览器中,可以携带上对应cookie。谷歌浏览器可以在地址栏中输入chrome://settings/siteData?search=cookie来查看当前浏览器保存的所有cookie,可以看到每个cookie是哪个域下面的。cookie 长度不超过 4KB ,否则会被截掉。每个域名下的cookie数量是有限制的,不同的浏览器默认的数量限制可能不同,ie7之前是20个,ie7之后和Firefox一样都是50个,chrome 和 Safari 没有做硬性限制。

先贴一张cookie认证流程图:

cookie认证的登录超时一般是服务端设置cookie的有效时间。cookie认证特点最大的就是用户信息保存在浏览器,早期互联网环境还比较安全,后来大家发现请求一旦被拦截,被拿到cookie后用户信息就泄露了,然后开始给cookie中的用户信息加密,但这也是治标不治本的方法,只要用户信息是在浏览器,终究是不安全的,最大的问题还是用户信息保存在浏览器的话,服务端不好管理受限太多。而且虽然大部分浏览器都是默认开启cookie存储的,可是万一谁设置了一下不存储cookie呢,那岂不是登录不了系统了。还有就是浏览器一次请求会把对应域中的所有cookie全部带上,可以如果我只需要带有用户信息的cookie用来做验证呢,其他cookie岂不是白白增加了请求包大小,也是带宽的浪费。

可见cookie认证的缺点还是很多的,所以现在的Web应用一般都不用cookie认证了,后来出现了session认证。

2.session认证

session是存储在服务端web容器中,也就是内存里的东西,除非特意删除,生命周期和整个容器一致。里面存储的数据格式也是键值对。当访问服务器否个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫session,而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口,或者是浏览器的子窗口,意思就是,只允许当前这个session对应的浏览器访问,就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话,就会再启一个属于自己的session。

贴一张session认证的流程图:

 

session认证和cookie认证最大的区别就是用户信息是保存在服务端的,这就大大减少了安全风险,浏览器有的只是去服务端找对应session的sessionId。可以看出session认证还是依赖于cookie机制的,所以除了比cookie安全点外,cookie认证的其他缺点session几乎也都有,比如浏览器设置了不存储cookie就登录不了了,还有一次请求携带多余cookie等问题。session认证还有一个致命的缺点,由于session是占用了服务器内存,随着系统登录用户越来越多,宝贵的内存资源就被会占用很多,这是最大的缺陷,但这一点一般在用户不多的中小Web应用中不用理会。

session认证在集群环境中也是有问题的,比如第一次访问是路由到了节点A然后登陆了,session创建在了节点A上,第二次访问路由到了节点B,虽然通过nginx的反向代理可以解决跨域问题,cookie是可以带过去,但是节点B上面没有session啊,难不成又要登录一遍?解决办法就是利用Spring Session或者自己用Redis做session共享,或者直接在nginx上配置ip_hash,使得同一个ip始终路由到同一个节点。

虽然session仍然有缺陷,但是现在大部分的Web应用还在使用session认证。后来出现了token认证。

3.token认证

token又叫令牌,本质上就是一串无意义的字符串,一般放在请求头里,请求头key一般是"Authorization",当然也可以和服务端约定好自定义成其他的,只要服务端能够从请求头中拿到token就好了。token认证的出现最大的特点就是让登陆认证不再依赖于cookie机制了,将token放在了请求头里,那些由于cookie机制导致的弊端自然就没有了。

贴一张token认证的流程图:

token认证最大的好处就是支持移动设备,因为移动端是不支持cookie的,自然cookie认证和session认证就用不了了。又不依赖cookie机制,用户信息又是服务端管理的,session认证看上去貌似没什么毛病了。但是慢慢的大家发现,怎么每次请求都要用token去数据库中查询用户信息,这样是不是数据库的压力太大了。

由于token是一串无意识的字符串,那能不能让token变得有意义呢,如果token携带了用户信息,不就不需要每次请求都访问数据库查了嘛,从token中直接解析出用户信息以及用户登录状态进行校验,这就是后来的JWT。给浏览器返回的token是一串带着用户信息的字符串,这一点就和最初的cookie认证比较像了。

4.JWT认证

JWT全称是Java  Web  Token。其实就是特殊的token,理解起来就是携带着用户信息的token。所以JWT认证和token认证本质上是一样的,只不过token认证的用户信息是从数据库里查出来的,而JWT认证的用户信息是直接从这个特殊的token中解析出来的。

虽然差不多,还是贴一张JWT认证的流程图:

上面都是单系统登录中的流程图,随着系统复杂性越来越高,在多系统之间的单点登录也必不可少。单点登录都要有一个专门的认证中心服务器,这和之前登录验证都在应用服务器上做不同。

cookie认证已经逐渐被淘汰了就不说了,基于token认证也是不适合应用于单点登录的,可以想象一下,单系统登录的token校验工作是在服务端进行的,而如果应用于单点登录,那必然是要在认证中心进行。如果每次请求中携带的token,都要由应用服务器去请求一遍认证中心去校验token,那也太麻烦了,认证中心的压力就太大了。所以一般说基于token的单点登录都是指基于JWT的单点登录,因为JWT的校验是可以在各个应用服务器上进行的,不需要每次都去请求认证中心。而剩下的基于session认证方式也对应的单点登录解决方案,因为基于session认证的单点登录有一个局部会话的概念,也不需要每次去认证中心校验。

1.基于session认证的单点登录

基于session认证的单点登录中还有局部会话和全局会话两个概念,即浏览器和应用服务器之间建立的是局部会话,和认证中心服务器之间建立的是全局会话,也就是用户登录成功之后,在认证中心服务器和应用服务器上都保存着包含用户信息和登录状态的session,浏览器中的表现就是应用服务和认证中心服务的域下面都会有对应的存着sessionId的cookie。

比如我在feedbackuat单点登录成功之后,feedbackuat和ssouat都会有cookie。

先贴一下基于session认证的单点登录流程图,这图把我画懵了:

需要注意的是,基于session认证的单点登录在集群环境中是不需要做session共享或者nginx配置ip_hash的。集群中各个节点就相当于各个子系统了,没有局部会话session那就重新走一遍自动单点认证呗,反正不需要用户手动再输一遍密码就好了。

为了验证这一点我用nginx配置了一个项目的集群环境,这个项目是集成了单点登录的,把ip_hash注释掉了,并且增加了两个响应头标识一下路由到了哪台服务器:

然后刷新页面看看是不是即使路由到了不同的服务器,也不需要单点登录:

 就刷新了一次,不同的请求路由到了不同的节点,但是不需要重新登录。

java实现基于session认证的单点登录需要两个jar包,cas-client-core和cas-server-core,即cas客户端和服务端,cas客户端就是图中的服务器A和B,cas服务端就是认证中心。这里主要看一下cas-client-core这个jar包,从中捋出部分源码对应一下图中的流程。

在AuthenticationFilter的doFilter()方法中,服务端校验如果局部会话和ticket都没有,则将浏览器重定向到单点登录地址:

需要注意的是,上图中拿ticket只是尝试拿,方法前缀有safe,因为ticket是认证中心的登录接口返回的,而认证中心的登录接口是需要开发的,自然各种各样的方式返回ticket给客户端,所以cas-client-core包中是不会有拿ticket然后去校验然后创建本地局部会话这个过程封装的,这个过程需要我们自己写,自定义一个过滤器实现它的AbstractCasFilter,然后在自定义的doFilter()方法中实现这段逻辑:

这是自定义的过滤器,这里面拿ticket和AuthenticationFilter中拿ticket的方法是一样的,这是因为在认证中心使用的也是cas默认的放ticket的方式,也就是作为url参数,参数key就是"ticket":

2.基于JWT认证的单点登录

其实单点登录的过程都差不多,就是认证方式的区别,理解了基于session认证的单点登录后,也很好理解基于JWT认证的单点登录。

 jwt的token校验都是在应用服务器上。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值