单点登录与JWT

JWT 全称: Json Web Token 。作用: JWT 的作用是 用户授权(Authorization) ,而不是用户的身份认证(Authentication) 。用户认证 指的是使用用户名、密码来验证当前用户的身份,即用户登录。用户授权 指用户登录成功后,当前用户有足够的权限访问特定的资源。

传统的 Session 登录:

  • 用户登录后,服务器会保存登录的 Session 信息
  • Session ID 会通过 cookie 传递给前端
  • http 请求会附带 cookie
    这种登录方式称为 有状态登录 。

一、

1、有状态登录(Session):

传统上,我们会使用 Session 和 Cookie 来保存用户的授权信息。第一步,登录过程,用户使用用户名和密码来登录系统,服务器会来验证用户名和密码是否正确,如果正确,服务器会给这个用户创建一个包含用户登录信息、角色、权限的一个叫做 Session 的东西,然后把这个 Session 保存起来,同时把这个 Session 的 ID 以 Cookie 的形式发送给前端,表示用户验证成功,登录完成了;接下来如果用户希望访问某些资源,前端要向后端发起一个 HTTP 的请求,同时相应的 Cookie 也会跟随请求一起发送给服务器,而服务器取得 Cookie 以后就会去查找是否有 Session ID ,然后通过 Session ID 提取相应的 Session 来确定用户的身份与权限,如果 Session 与 ID 相符,同时用户的信息也能提供相应的权限,服务器就会认为这个用户已经登录了,随后资源信息就会通过 HTTP 响应给前端。
客户端 服务器 POST api/login{email,password} 通过 cookie 传递 session ID 请求携带 cookie ,并包含 sessionID 如果用户认证成功,则返回资源 用户登陆 访问资源 创建并保存 session 通过sessionID 来确定用户 身份与权限 有状态登陆(Session)

2、无状态登陆(JWT):

第一步,同样是登陆,用户使用用户名和密码登陆,如果登陆成功,服务器就会返回一个加密文档,这个文档就是 JWT ,其中包含用户密码以外,全部的认证信息,包括用户名、Email、角色、权限等等,而前端在拿到 这个JWT 以后就可以把它保存起来了,可以保存到 Cookie 中,也可以保存到浏览器的 LocaStorage 里面,而生成的 JWT 不需要在后端保存,接下来第二步,用户如果需要访问某些权限的时候,这时候,用户就要把 JWT 放在 HTTP 请求 herder 中与请求一起发送给服务器,服务器取得 JWT 以后 会使用私钥给 JWT 文档解密 ,如果解密成功而且数据依然有效则代表用户已经登陆了,如果 JWT 所描述的用户权限允许该用户访问资源,那么服务器就会把资源的信息,通过 HTTP 响应发回给前端。
客户端 服务器 POST api/login{email,password} 返回 JWT 请求携带 JWT 如果 JWT 有效则返回资源 用户登陆 访问资源 使用密码加密 JWT 使用相同的密码验证JWT 无状态登陆(JWT)3、区别与差异:

传统上用户登陆状态会以 Session 的形式保存在服务器上,而 Session ID 则保存在前端的 Cookie 中;而使用 JWT 以后,用户的认证信息将会以 Token 的形式保存在前端,服务器不需要保存任何的用户状态,这也就是为什么 JWT 被称为无状态登陆的原因,无状态登陆最大的优势就是完美支持分布式部署,可以使用一个 Token 发送给不同的服务器,而所有的服务器都会返回同样的结果。

二、

1、有状态登陆

这样做的缺点是什么?
服务端保存大量数据增加服务端的压力
服务端保存用户状态,无法进行水平扩展(集群)→针对Session来说
客户端请求依赖服务端,多次请求必须访问同一台服务器→针对Session来说
(如果域名不同那么 Session域很难进行处理)

2、无状态登陆

无状态登陆的流程:

  • 当客户端第一次请求服务时,服务端对用户信息进行信息认证(登陆)
  • 认证通过,将用户信息进行加密形成token,返回客户端,作为登陆凭证
  • 以后每次请求,客户端都携带认证的tocken
  • 服务端对tocken进行解密,判断是否存在

服务器不保存用户的登录信息!

微服务集群中的每个服务,对外提供的都是Rest风格的接口。而Rest风格的一个最重要的规范就是:服务的无状态性,即:

  • 服务端不保存任何客户端请求者信息
  • 客户端的每次请求必须具备自描述信息(jwt),通过这些信息识别客户端身份

带来的好处是什么呢?

  1. 客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同一台服务
  2. 服务端的集群和状态对客户端透明
  3. 服务端可以任意的迁移和伸缩
  4. 减小服务端存储压力

JWT官网: https://jwt.io/

JWT交互流程:

  • 授权流程:

    • 1、用户请求登录,携带用户名密码到授权中心
    • 2、授权中心携带用户名密码,到用户中心查询用户
    • 3、查询如果正确,生成JWT凭证
    • 4、返回JWT给用户
  • 鉴权流程:
    • 1、用户请求某微服务功能,携带JWT
    • 2、微服务将jwt交给授权中心校验
    • 3、授权中心返回校验结果到微服务
    • 4、微服务判断校验结果,成功或失败
    • 5、失败则直接返回401
    • 6、成功则处理业务并返回

因为JWT签发的token中已经包含了用户的身份信息,并且每次请求都会携带,这样服务的就无需保存用户信息,甚至无需去数据库查询,完全符合了Rest的无状态规范。

不过,这个过程是不是就完美了呢?

可以发现,用户访问我们的网站,一次授权后,以后访问微服务都需要鉴权,那么每次鉴权都需要访问授权中心,一个用户请求,被分解为2次请求才能完成,效率比较低。

能不能直接在微服务的完成鉴权,不去找授权中心呢?

如果这样,就可以减少一次网络请求,效率提高了一倍。但是,微服务并没有鉴定JWT的能力,因为鉴定需要通过JWT来完成。我们不能把JWT交给其它微服务,存在安全风险。

怎么办?

这就要用到RSA非对称加密技术了。

三、非对称加密验签

1、加密技术的类型

加密技术是对信息进行编码和解码的技术,编码是把原来可读信息(又称明文)译成代码形式(又称密文),其逆过程就是解码(解密),加密技术的要点是加密算法,加密算法可以分为三类:

  • 对称加密,如AES

    • 基本原理:将明文分成N个组,然后使用**对各个组进行加密,形成各自的密文,最后把所有的分组密文进行合并,形成最终的密文。
    • 优势:算法公开、计算量小、加密速度快、加密效率高
    • 缺陷:双方都使用同样**,安全性得不到保证
  • 非对称加密,如RSA
    • 基本原理:同时生成两把**:私钥和公钥,私钥隐秘保存,公钥可以下发给信任客户端

      • 私钥加密,持有私钥或公钥才可以解密
      • 公钥加密,持有私钥才可解密
    • 优点:安全,难以**
    • 缺点:算法比较耗时
  • 不可逆加密,如MD5,SHA
    • 基本原理:加密过程中不需要使用**,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,无法根据密文推算出明文。

2、非对称加密验签

有了非对称加密,我们就可以改变签名和验签的方式了:

  • 生成RSA**对,私钥存放在授权中心,公钥下发给微服务

  • 在授权中心利用私钥对JWT签名

  • 在微服务利用公钥验证签名有效性

因为非对称加密的特性,不用担心公钥泄漏问题,因为公钥是无法伪造签名的,但要确保私钥的安全和隐秘
非对称加密后的授权和鉴权流程:

授权中心的主要职责:

  • 用户登录鉴权:

    • 接收用户的登录请求,
    • 通过用户中心的接口校验用户名密码
    • 使用私钥生成JWT并返回
  • 用户登录状态校验
    • 判断用户是否登录,其实就是token的校验
  • 用户登出
    • 用户选择退出登录后,要让token失效
  • 用户登录状态刷新
    • 用户登录一段时间后,JWT可能过期,需要刷新有效期

我们把jwt返回到客户端,客户端保存到哪里呢?

列举两种解决方案:(还可以用redis)

  • 方案一:存入web存储如:LocalStorage或SessionStorage中

    • 优点:

      • 不用担心cookie禁用问题
      • 不会随着浏览器自动发送,可以减少不必要的请求头大小
    • 缺点:
      • 不会随着浏览器自动发送,需要前段额外代码,携带jwt
      • 会遭到XSS(跨站脚本)攻击
  • 方案二:存入cookie
    • 优点:

      • 会随着浏览器自动发送,客户端不用任何额外代码
      • 使用httponly,避免XSS攻击风险
    • 缺点:
      • 会随着浏览器自动发送,某些时候有些多余
      • 可能遭到CSRF(跨站资源访问)攻击

这里我们采用哪一种呢?

我们采用cookie方案,cookie方案的两个缺陷我们也可以解决:

  • 问题1:会随着浏览器自动发送,某些时候有些多余

    • 解决:后端服务与其它服务资源(如静态资源)采用不同域名,浏览器的同源策略会限制cookie
  • 问题2:可能遭到CSRF(跨站资源访问)攻击
    • 解决:避免get请求操作服务器资源,遵循Rest风格,必要时在token中存入随机码

JWT内部设置了token的有效期,默认是30分钟,30分钟后用户的登录信息就无效了,用户需要重新登录,用户体验不好,怎么解决呢?

JWT的缺点就凸显出来了:

  • JWT是生成后无法更改,因此我们无法修改token中的有效期,也就是无法续签。

怎么办?

3种解决方案:

  • 方案1:每次用户访问网站,都重新生成token。操作简单粗暴,但是token写入频率过高,效率实在不好。
  • 方案2:登录时,除了生成jwt,还另外生成一个刷新token,每当token过期,如果用户持有刷新token,则为其重新生成一个token。这种方式比较麻烦,而且会增加header大小。
  • 方案3:cookie即将到期时,重新生成一个token。比如token有效期为30分钟,当用户请求我们时,我们可以判断如果用户的token有效期还剩下15分钟,那么就重新生成token,可以看做上面两种的折中方案。

来源:

https://www.freesion.com/article/4184756009/

https://blog.csdn.net/weixin_45581482/article/details/119336595

https://blog.csdn.net/fhkkkbfgggjk/article/details/85047461

JWT有状态登陆与无状态登陆相关推荐

  1. 单点登陆和无状态登陆

    很多人都听说过单点登陆.今天我们来说说什么是单点登陆和无状态登陆. 传统的项目都是使用session来验证登陆,但是在分布式项目中使用session是不行的.因为每个服务都是一个独立的项目,那么我们将 ...

  2. 有状态bean与无状态bean

    在学习bean的作用域的时候,了解了这个问题. bean5种作用域:分别是:singleton.prototype.request.session.gloabal session 接下来就讲一下有状态 ...

  3. 「小程序JAVA实战」java-sesion的状态会话与无状态会话(38)

    转自:https://idig8.com/2018/09/02/xiaochengxujavashizhanjava-sesiondezhuangtaihuihuayuwuzhuangtaihuihu ...

  4. (3) ebj学习:有状态bean和无状态bean区别

    1 区别 有状态bean : 客户端通过JNDI访问有状态bean, 服务端new该bean,并返回该代理对象 有状态bean : 客户端通过JNDI访问有状态bean, 服务端该bean是单例模式, ...

  5. 【转】多线程之有状态对象和无状态对象

    有状态对象和无状态对象 参考:https://www.cnblogs.com/xubiao/p/6567349.html 一. 基本概念 1. 什么是有状态对象 有状态对象指的是有数据存储功能的类的对 ...

  6. mysql有状态无状态_k8s statefulSet 有状态应用和无状态应用区别

    一.定义: 无状态服务:就是没有特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息) 有状态服务 ...

  7. 状态服务器与无状态服务器(要点)

    对服务器程序来说,究竟是有状态服务,还是无状态服务,其判断依旧是指两个来自相同发起者的请求在服务器端是否具备上下文关系.如果是状态化请求,那么服务器端一般都要保存请求的相关信息,每个请求可以默认地使用 ...

  8. EJB3.0框架实例----区分有状态bean和无状态bean

    1.通过这个例子可以区分,有状态bean和无状态bean中的数据会不会混淆; 2.一种取巧的做法是:在建立的客户端的工程上右键,选择build path--->把服 务端的EJB工程导入的,新建 ...

  9. 关于drools有状态会话和无状态会话到底有何区别的看法

    关于有状态会话和无状态的会话的区别,很多人不能真正理解,小哥也不是很理解,但也有些看法,以下是官网翻译而来 一.有状态会话常见用例: 1. 监测 半自动买入股票市场监控与分析.  2. 诊断  故障查 ...

  10. Java - 有状态bean和无状态bean

    有状态Bean和无状态Bean的本质区别:声明周期 1. 前言:EJB EJB:称为企业Java beans,是基于分布式事务处理的企业级应用程序的组件. Sun公司发布的文档中对EJB的定义是:EJ ...

最新文章

  1. Ubuntu设置RS-232串口登陆终端(译文,节选)
  2. DevC++最新汉化版(支持C++11)
  3. 苹果是c语言安卓是什么语言,主流app是用什么语言开发的苹果和安卓的主流开...
  4. nlp 财务提取_RPA,智慧财务时代的“珍妮纺织机”来了?
  5. python保存csv_在python中修改和保存csv文件
  6. 结合二维码打造安全的手机远程运维管理平台
  7. 我的KT库之-----缓存与配置
  8. BASH 进阶(转载防丢)
  9. 微信功能栏Android代码,微信隐藏代码合集 你不知道的微信隐藏代码功能
  10. java dateutils工具类_DateUtils 日期工具类
  11. Word参考文献自动编号
  12. 【更新中】SmartGit 注册码 算法注册机
  13. linux基础教程 黑鹰基地Linux运维特训班
  14. python getcwd_python – 执行os.getcwd()时出错?
  15. 5G使用随笔-华为5G模块MH5000-31
  16. 定制自己的报表!7款实用开源报表工具
  17. ios label文字行间距_UILabel UITextField调整行间距【原创】
  18. pod的调度策略、定向调度、亲和性调度、污点、容忍污点
  19. 模仿,类比,移植技法(创新技法5)
  20. 厦门工程技术人员职称申报操作笔记 01 继续教育学时

热门文章

  1. 选择结构【C语言程序设计】
  2. Gartner谈元宇宙
  3. 征程留给骏马,我只不过是头老骥
  4. git pull远程master_git pull拉取远程指定分支
  5. 拓扑排序和关键路径的图形化显示
  6. 产业互联网周报:百度智能云高管大调整;安谋科技“夺权”风波近尾声;海康威视就回应美国制裁;受东数西算提振,西部地区投资同比涨6倍...
  7. 先学vb还是python_一个初一学生学习编程先学VB好呢还是Python?
  8. windows电脑插入耳机自动提示不会自动出现的简单解决方案?
  9. Flexsim案例分析2
  10. 游戏中 ----三维空间中的 向量