SpringBoot中Token登录授权、续期和主动终止的方案流程分析

 更新时间:2024年09月24日 16:36:39   作者:码到三十五  
SpringBoot项目中,基于Token的登录授权方案主要有两种:利用Session/Cookie和JWT,Cookie/Session方案有状态,不适合分布式架构,而JWT虽无状态,但存在过期时间不可强制失效、一次性等缺点,本文介绍SpringBoot中Token登录授权、续期和主动终止的方案,感兴趣的朋友一起看看吧

SpringBoot项目要写登录注册之类的方案
使用Cookie或Session的话,它是有状态的,不符合分布式技术架构
使用Security或者Shiro框架实现起来比较复杂,一般项目无需用那么复杂
使用JWT它虽然是无状态的,也可以载荷用户数据,但还是有很多缺点:
- 缺点1:设置过期时间后,无法强制让它过期,在有效期内它始终可用
- 缺点2:一次性的,如果用户数据有变,只能重新生成新的JWT

以前登录Token一般是放在服务端的Session中,Session有过期时间,也会自动延期,当然我们现在绝大部分项目都不会使用session来存储了。

1、Redis+Token方案的授权流程

SpringBoot用普通的UUID作为token,返回到前端后,前端每次请求都会带上这个token作为授权凭证。这种方案是能够自动续签,也能做到主动终止。所以很多项目用的都是Redis+Token方案,简单方便问题少。缺点就是需要依赖Redis和数据库。

流程 + lua优化 :

  • 设置一个拦截器,不校验登录接口,拦截其他接口
  • 登录接口接收前端传来的用户名密码,去数据库查询该用户名是否存在,该密码是否正确
  • 如果正确则表示登录成功,调用生成Token方法,返回Token给前端
  • Token使用用户id或账号+时间戳+UUID用MD5加密的一串字符串(不建议用其他数据,因为id或账号极少变更的,变更会增加复杂性)
  • 生成后存储到Redis,把Token当作键,用户数据当作值,并设置过期时间
  • 生成Token的方法中,还得防止重复调登录接口,不停生成不同的Token,所以先判断数据库中是否存在键,所以保存token键到redis的同时要在redis中再增加一条用户ID为键Token为值的数据,可以验证该用户是否已经生成过token

SpringBoot DEMO代码:

接下来是校验其他接口方法,同时也做了验证和续期

2、JWT方案的的授权流程

2.1 JWT带来的续签和终止问题

JWT的优势在于无状态,也就是生成的Token中本身有存储信息,所以不需要依赖Redis和DB。JWT本身也有有效期参与签名,问题在于这个有效期不能更改,也很好理解如果参与签名的参数(有效期)发生变化,Token也就不一样了。如果有效期不能改变,即便时间设计的再长,也会有到期的时候,而且Token这种设计初衷也不能有效期很长,导致用户在操作过程中Token到期授权失败,这种情况根本是无法接受的。

另外,JWT的Token签发之后,理论上在到期之前是始终有效的,在有些场景下,比如用户更改/重置密码,踢出登录(单一用户登录),都需要让对应用户在其他电脑(终端)上自动退出登录,也就是要让其他的Token马上失效,所以需要额外设计来解决这两个问题。

2.2 解决JWT自动续签有几个解决方案

  • 每次请求都返回新的Token,这种简单粗暴,不存在续签的问题,不过相信很多人不会用,请求量大的话性能损耗也是比较明显。
  • 生成的JWT,不加入过期时间,在服务端Redis额外存储一个对应的过期时间,并每次操作延期。这种设计感觉很多余,既然保存到了Redis,JWT从无状态变成了有状态,既然能够保存过期时间,为啥不把用户信息都保存到Redis中,何必用JWT加密后前后端传来传去没有意义。
  • 临近过期刷新JWT,返回新的Token,很多人也采用的是这种方案。

2.3 解决JWT主动终止问题

  • JWT签发后就生效,无法做到主动终止,那还是用到Redis,把用户id作为key,生成一个用户唯一ID(用户指纹)存入Redis,并参与JWT签发过程;
  • 如果更改了密码需要终止其他所有已经签发的JWT,只需要更改这个用户指纹;
  • 在JWT验签过程中,验证用户指纹,如果和JWT中信息不一致授权失败,也就是做到了主动终止JWT的目的。
  • 需要注意的是,在高并发过程中写入用户指纹过程可能要用到分布式锁。

到此这篇关于SpringBoot中Token登录授权、续期和主动终止的方案的文章就介绍到这了,更多相关SpringBoot Token登录授权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Java中的Lambda表达式

    详解Java中的Lambda表达式

    Lambda表达式是Java SE 8中一个重要的新特性。这篇文章主要介绍了Java中的Lambda表达式 ,需要的朋友可以参考下
    2019-04-04
  • java观感示例分享

    java观感示例分享

    这篇文章主要介绍了java观感示例,该实例查询并生成了系统中存在观感对应的按钮并在用户点击相应按钮时将窗口的观感切换到指定的观感上
    2014-03-03
  • js+java实现登录滑动图片验证

    js+java实现登录滑动图片验证

    这篇文章主要为大家详细介绍了js+java实现登录滑动图片验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • ElasticSearch合理分配索引分片原理

    ElasticSearch合理分配索引分片原理

    这篇文章主要介绍了ElasticSearch合理分配索引分片原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java多线程编程实战之模拟大量数据同步

    Java多线程编程实战之模拟大量数据同步

    这篇文章主要介绍了Java多线程编程实战之模拟大量数据同步,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02
  • java jpa如何自定义sql语句

    java jpa如何自定义sql语句

    这篇文章主要介绍了java jpa如何自定义sql语句方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java clone方法详解及简单实例

    Java clone方法详解及简单实例

    这篇文章主要介绍了 Java clone方法详解及简单实例的相关资料,需要的朋友可以参考下
    2017-03-03
  • JAVA图形界面(GUI)之表格的示例代码

    JAVA图形界面(GUI)之表格的示例代码

    这篇文章主要介绍了JAVA图形界面(GUI)之表格的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Maven发布项目到Nexus私有服务器

    Maven发布项目到Nexus私有服务器

    本文主要介绍了Maven发布项目到Nexus私有服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 基于Java实现一个简单的图片加载器

    基于Java实现一个简单的图片加载器

    这篇文章主要为大家详细介绍了如何使用Java 2D API(Java的绘图和图像API)来实现图片加载和显示,文中的示例代码讲解详细,需要的小伙伴可以参考一下
    2023-11-11

最新评论