前后端分离,使用JWT做状态保持,实现和传统session一致的效果

1、背景

springcloud+前端 越来越成为现在软件公司的架构选择,采用这种架构+docker能非常方便的实现系统的弹性伸缩。这里我们讨论一个采用此架构会遇到的问题,就是状态保持。

2、方案选择

前后端分离,状态保持方案非常多,jwt是一种轻量级的、简单的方案。主要思路是后端拿着用户名、密码请求后端,后端验证通过后,返回给前端一个token(包含用户id、过期时间等的json),这个token是个加过密的json字符串。前端把这个字符串放在http请求头(可以跨域,放在cookie就没法跨域),每次请求都带上这个参数,后端就能验证当前用户。

3、诉求

我们要实现和传统session方式一样的效果:比如超时时间是30min,如果超过30min未做任何操作,必须强制跳转登录页面;如果30分钟内有操作,过期时间要刷新(重新计算30min)。

4、调研

网上看了很多方案,有很多思路都是使用两个token:access_token、refresh_token,如果access_token过期,则使用refresh_token去刷新access_token。 由于refresh_token长期有效,因此我们不能“只要access_token过期就刷新”,必须判断出需要重新登录或者需要自动刷新token。

我们延用以上思路实现诉求:后端提供颁发、验证、刷新接口;控制刷新交给前端,因为后端是无状态的,类似session的处理放在前端比较好。思路如下:

  • 用户使用用户名、密码获取token,获得access_token、refresh_token,refresh_token的内容主要是用户信息(用户名、密码),用来刷新access_token。第一次获取access_token,本机存储记录一个refresh_time,记录token刷新时间。后续用户每次访问后端的URL都更新这个时间(axios有拦截器)。
  • 如果后端返回401,说明token已经过期。此时判断(当前时间-refresh_time)是否大于30min,如果未超过,说明之前有操作,需要刷新保持状态。如果大于30min,则说明用户长时间未操作,必须重新登录。

流程图如下:

前后端分离,使用JWT做状态保持,实现和传统session一致的效果_第1张图片

也即是通过一个refresh_time来定位是正常超时,还是需要刷新,能做到和web容器的session方式效果一致。

刷新接口:

刷新接口也需要判断refresh是否过期,极端情况,用户最后一次操作时间卡在超时时间前的最后一秒,为了保证refresh_token可用,refresh_token的超时时间设置为access_token的两倍即可。刷新接口既刷新access_token,也刷新refresh_token。

有问题欢迎拍砖。

你可能感兴趣的:(架构,前端)