转自:https://www.cnblogs.com/shiyajian/p/10672908.html

前言

我们在设计构建一个系统的时候,权限管理和用户认证是最基本功能,其中关于用户认证这块是一个比较常见的模块。在已有的方案中,我们最常见的就是保存到 tomcat 中的 session 对象中。随着微服务的兴起,一种新的认证方法又火了起来,那就是JWT,下面我就浅析下自己对两种认证方式的认识,一些经验和大家探讨。

浅谈认证

我对认证的理解就是,当一个设备(客户端)向一个设备(服务端)发送请求的时候,服务端如何判断这个客户端是谁。传统意义有两种认证方式:有状态认证、无状态认证。有状态和无状态最大的区别就是服务端会不会保存客户端的信息。

有状态认证

有状态的认证,以 cookie - session 模型为例,当客户端第一次请求服务端时候,服务端会返回客户端一个唯一标识(默认在cookie中),并保存对应的客户端信息。客户端接受到唯一标识之后,将标识位保存到本地cookie中,以后的每次请求都携带此 cookie ,服务端根据此 cookie 标识可以判断请求的用户是谁,然后查到对应用户的信息,大概示意图如下:

请求认证过程(以tomcat为例):

1、客户端向服务端发起请求;

2、第一次客户端发起请求,服务端创建一个 key 为JSESSIONID的值,并写入到客户端的cookie中,同时在服务端的Session Manager中创建一个对象,保存这个 JSESSIONID 对应的信息;

3、以后客户端每次请求,都会根据cookie进行区别,我们可以通过 session.setAttrbutie,session.getAttrbuite 等方法,拓展用户信息,根据用户信息做一些业务判断等;

4、Session Manger 中维护有一个定时器,当 JSESSIONID 对应的信息长时间没有访问(默认30分钟),或者显性调用 session.invalidate 方法,那么这个对应的信息将会被删除。

那么针对有状态的认证,我们分析下他的利弊:

优势

因为客户端的信息都保存在服务端的 Session Manager 中,如果要将客户端的认证信息取消,只需要将对应的session 信息删除即可,及时响应,方便快捷。

劣势

1、因为服务端保存着客户端的信息,当用户量特别多时候,服务端需要特别的内存资源;

2、如果失效时间特别长的情况下,大量资源被占用无法释放,如果释放,那么相当于用户的注销登录;

3、客户端的信息在服务端中维护,如果服务端为集群的场景下,那么客户端信息不共享,必须使用分布式 session 或者其他方案;

4、cookie有同源策略和跨域限制,部分业务场景下cookie并不能传递;

5、部分设备本身不支持cookie或者禁用cookie,还有的手机浏览器也不支持cookie。

应用实战

1、如果公司以集群式部署多台服务,那么可以采用的策略有:配置负载均衡的路由策略为hash一致算法(不推荐),如果某个机器停机,那么会重新分配到新机器,又需要重新登录;session复制方式(不推荐),复杂度过高;分布式 session 方案(强力推荐),目前市场上有 spring-session 的依赖,可以将 session 保存的容器从应用内部抽取到 redis 或者 数据库中供多个应用使用,实现集中管理,为了保证设备的兼容性,spring-session提供了将认证方式从cookie修改为header,web网站可以保存到 SessionStorage,移动端可以保存到本地缓存中。

2、如果一个公司有多个产品需要共享认证信息,此时需要使用 SSO Server。

无状态

无状态的认证,客户端在提交身份信息,服务端验证身份后,根据一定的算法生成一个 token 令牌返回给客户端,之后每次请求服务端,客户端都需要携带此令牌,服务端接受到令牌之后进行校验,校验通过后,提取令牌中的信息用来区别用户,大概的示例图如下:

请求认证过程:

1、执行登录操作,用户端发送账号密码等信息;

2、服务端校验账号密码是否正确,如果正确,根据对应的用户信息和服务端秘钥生成 JWT 令牌,然后通过response.setHeader 返回给客户端(此处假设生成了一个名为 x-auth-token 的令牌);

3、客户端在返回成功之后,将Header中的x-auth-token 保存到本地的LocalStorage中;

4、客户端在以后每次请求服务端时候,都在header中携带x-auth-token令牌的值;

5、服务端每接受到请求之后,判断hader中是否包含x-auth-token,token 是否有效,然后通过 BASE 64 算法 decode,根据解密后的参数,判断当前 token 是否在有效期,所访问的接口是否有权限等操作。

优势

1、因为服务端不保留客户端的任何信息,每次只需要通过特定的算法进行校验,节省了大量存储空间;

2、方便水平扩容,不需要 SSO Server,只要保证新的应用采用同样的验证算法,就可以验证通过并获得对应信息。

劣势

当客户端的token被盗用,或者需要手动封禁某个用户的时候,没办法对此token进行操作,必须等待token失效(如果在服务端维护token和用户的关系,技术可以实现,但是违背无状态的设计理念)。

应用实战

1、生成的 token 中携带用户常用信息,但是不携带用户的敏感信息,比如密码手机号等等,因为这些信息通过BASE 64 可以解密出来的;

2、要处理服务端主动禁用某个 token ,可以采用黑名单措施,每次请求前判断当前token是否已经被禁用;

3、token 中的信息除了基本信息外,还应该携带比如签发时间、有效时间、刷新token等字段,用来处理token的续约问题。

总结

在实际的项目中,我们该如何选择认证模式,是有状态的认证还是无状态的认证呢?以前看文章时候,在掘金中看到有人把 JWT 批评的一无是处,就和垃圾一样。我个人觉得吧技术没有谁好谁坏,谁旧谁新,也没有谁该被时代淘汰,存在及合理,我们需要充分理解需求,合理使用技术,只有最合适的技术才是最好的选择。 下面是我关于技术选型时候的一些个人观点,希望大家批评指正和交流。

在我的经验中,目前比较流行的就是互联网APP中大部分采用 JWT 的认证方式,一些企业内部管理系统则大部分采用 cookie-session 的机制,大量的商业案例下,我个人分析推测的原因可能如下:

1、在互联网APP产品中,尤其以 to C 模式,用户量极大,为了用户体验,一般会将登录信息保留特别长时间,某些APP 只要你不卸载,那么不管几个月之后登录,账户还是处于登录状态。在这种情况下,假如采用 cookie-session 机制,那么你的用户信息保存很多个月,用户量特别大的情况下,会造成大量资源占用和浪费,这种场景采用 JWT 就是相对比较好的方案。

2、企业内部管理系统有以下特点:用户量较少(最多最多不超过10W人),信息安全要求高(及时踢出客户端登录状态,个人浏览器关闭账号退出登录),在这样的场景下占用的内存不会太多,所以基于 cookie-session 这种机制,是比较好的方案,如果企业内部还有其他应用需要集成时候,需要使用 SSO Server 实现。

代码案例

最近在找工作,如果闲下来有时间的时候会写两个项目出来,敬请期待:

1、 spring security + JWT 的验证案例

2、shiro + spring-session (header替换cookie)的验证方案

浅析权限认证中的有状态和无状态相关推荐

  1. spring期刊状态_无状态Spring安全性第2部分:无状态认证

    spring期刊状态 Spring Stateless Security系列的第二部分是关于以无状态方式探索身份验证的方法. 如果您错过了有关CSRF的第一部分,可以在这里找到. 因此,在谈论身份验证 ...

  2. 精通有状态vs无状态(Stateful vs Stateless)一

    精通有状态vs无状态(Stateful vs Stateless)-Immutable模式之姐妹篇 Peter Wei 我相信有不少人还不明白有状态和无状态(Stateful and Stateles ...

  3. mysql有状态无状态_有状态和无状态的对象区别

    每次的总结,都是一种进步,把自己理解的东西记录下来不容易,让别人看懂更不容易. 第一:基本概念: 1.有状态就是有数据存储功能.有状态对象(Stateful Bean),就是有实例变量的对象,可以保存 ...

  4. IPv6系列-彻底弄明白有状态与无状态配置IPv6地址

    深入研究自动分配IPv6地址的Stateless(无状态)与Stateful(有状态)方式 小慢哥的原创文章,欢迎转载 目录 小说搜索 biqi.org ▪ 一. Link-Local Address ...

  5. 有状态和无状态(@stateless/@stateful)

    基本概念:  有状态就是有数据存储功能.有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的.在不同方法调用间不保留任何状态.  无状态就是一次操作,不能保存数 ...

  6. 服务器的鱼和熊掌,有状态or无状态

    问题引入 如果我们刚开始新游戏项目的服务器开发,会遇到服务器状态选择问题,游戏项目是用有状态服务器还是无状态服务器? 是什么?     服务器状态简单来说客户端的多次请求具有上下文关系.比如客户端登录 ...

  7. 有状态和无状态(Stateful vs Stateless)

    我相信有不少人还不明白有状态和无状态(Stateful and Stateless)的概念,那么我们今天就来谈谈有状态和无状态,一方面不断总结提高自我,另一方面兼扫盲. 基本概念: 有状态就是有数据存 ...

  8. 有状态和无状态的区别

    基本概念: 有状态就是有数据存储功能.有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的.在不同方法调用间不保留任何状态. 无状态就是一次操作,不能保存数据 ...

  9. 分布式系统的基本术语之有状态、无状态

    一, 系统设计:有状态.无状态 惯例,先看栗子 网站登录校验,很普通的一个功能  对于这个功能我们要如何实现? 先分析一下登录校验是个啥意思  举个栗子,比如我们在登陆页输入用户名密码,登录了社交网站 ...

最新文章

  1. 中国“芯”的突破攻略——智源大会“智能体系架构与芯片”论坛发布
  2. linux(Ubuntu/Centos) iproute 路由IP地址等命令集合,查看端口链接
  3. 四周有阴影_四周窄边全功能TypeC 飞利浦256P1FR评测
  4. Layui 表格编辑
  5. 多数据中心的高可用结构【环状星型数据库架构】
  6. php面向对象魔术方法,PHP面向对象中的魔术方法
  7. java对多态的理解_对于Java中多态的理解
  8. heapsort(Java)(最小堆)
  9. SpringBoot异常处理机制之自定义404、500错误提示页面
  10. smobiler中实现页面切换_.Net语言Smobiler开发之如何在手机上实现表单设计
  11. SuperMap iClient3D for WebGL教程(特效)- 点光源
  12. 洛谷 P3957 跳房子
  13. Mockplus Cloud updated传达设计意图的新方法
  14. python中turtle隐藏画笔_python中Turtle的画笔命令有哪些?
  15. js里分割字符串,数组拼接
  16. LWN:Ubuntu 不再缺省提供Flatpak!
  17. 苹果几是双卡双待_iPhoneSE将于4月24日开卖:苹果A13+双卡双待,网友:等到了!...
  18. 【华为Atlas人工智能计算平台概述】
  19. 迪士尼也追踪游客数据,但它为什么没有被批判?
  20. python爬虫,wallhaven热门壁纸多线程采集下载源码

热门文章

  1. MongoDB简单概述
  2. python特定词频统计_词频统计方案与具体实现-elasticsearch、spark、python
  3. 过拟合和欠拟合_现代深度学习解决方案中的两大挑战:拟合和欠拟合
  4. mysql数据库druid密码加密_Druid数据库密码加密
  5. mysql 几种插入数据的方法
  6. 嵌入式 uboot引导kernel,kernel引导fs【转】
  7. ant+jenkins+testng+selenium集成环境搭建
  8. 一起谈.NET技术,ASP.NET MVC2.0在Tab页中实现异步无刷新分页
  9. shell之for循环使用---更新中
  10. JavaScript+Css实现的鼠标悬停时动态翻滚的紫色菜单导航