栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

自刷新Token——后端部分

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

自刷新Token——后端部分

Token后台逻辑

​ 这个是我和我的好朋友【Samuel_luo。】思考如何优化一个登录方式的过程,在他的博客中已经介绍了Token的流程和每一步的设计思路,详细可看:自刷新token——前端部分

​ 我在这里会对后台实现逻辑进行阐述,为防止有人没看过我亲爱的【Samuel_luo。】的博客就直接阅读本文,我在此简单介绍一下整体的结构:token 的 结构为 tToken + sToken + step 其中tToken为原始token,可以再这个token中存储信息,完成之前token的任何操作。sToken是基于tToken不断迭代而成的,用来校验本token是否正确。而step为步数,用来声明sToken迭代的次数。token传输不为明码,使用AES加密,密钥的确定使用RSA加密传输(效仿https)。

​ 首先,介绍一下对sToken实现的迭代方式,在我们讨论时出现了两种方式:

  1. 使用版本号控制的sToken刷新,也就是说,其实sToken不需要改变,只是需要给一个位置来确定他的版本号就行了,如果版本号不在双方认同的范围之内,那么sToken就相当于失效了。
  2. 使用一种方式可以使得sToken不断发生改变,比如我对sToken+1,那么对于后台看到传过来的sToken之后只需要在自身的基础上,同样完成+1的操作,再比对两者是否相同就可以完成sToken的校验。

​ 相较于这两种方式,我们选择了后者,因为我们设计这个token的最初逻辑就是希望可以防止一些高手,可以获取token,并对token做出一些改变传回后台,使得绕过了后台的检测机制,来保证安全性。如果采用前者,就比较容易再多次请求中总结出规律。

​ 而对于后者的+1操作,我们的sToken为String型,如果说,我们检查完step后发现需要迭代两次,那么我们可以实现sToken+1+1 == sToken+2吗?从做法上来讲可行,从逻辑上来说不建议,一是因为增加破解成本,sToken+1+1 != sToken+2这种做法,可以使得找规律的难度增加。二是,如果遵循了相等的法则,那么sToken就可以反向推出tTkoen,这是一个很危险的操作。所以我们的迭代方式采用的是对字符串进行MD5操作。

​ 然后因为不允许sToken+1+1 == sToken+2,所以在迭代sToken版本的时间复杂度为O(n);这个n为服务端与客户端的step的差值,如果这个差值过大,其实是有问题的,而且会导致迭代版本的时间过长,占用的服务器资源过多。所以这个step的差值一定小于10(这是一个值,在实现上可以设置为另一个更符合自己项目的值)。对于服务端保存的token,这个是已经被校验完了的,失效的token,是为了保证数据库被入侵时,获取到的数据皆为失效的。所以step一定是客户端大于服务端,即0 < ClientStep - ServerStep < 10.

​ step,是在服务端生成一个随机数,从0到100000;

​ 从实现上来讲,需要开发的就是三种类型的接口:

  1. 登录接口切面
  2. 登出接口切面
  3. 正常请求接口切面

​ 为了更便捷的实现这三种功能,采用了切面的方式对请求进行监管,利用properties注入监管函数的切面JoinPoint。切面如何实现的呢,在本文不再阐述了,有兴趣的可以自行了解一下。

登录接口切面

​ 对于登录来说,可以分为两种类型,一种是账号密码登录,一种是利用token自动登录,这两种的触发条件可以倚靠传入请求的header中有无token做出判断。当请求参数传来时,一定会携带一个叫做random-client的请求头,这是我们作为之后加密token的AESKey的一部分,由可客户端提供一部分,另一部分则需要服务端生成random-server,然后以一种规则凭借成AESKey = random-client + random-server;使用账号密码登录呢是切面实现上最简单的,毕竟切面就是为了增强函数。使用token自动登录,则需要我们主动向请求中传输信息,在这里有两中实现方式:一种为使用field修改函数的参数;另一种为使用ThreadLocal传入参数。我的实现方式为后者,相比较起来,这个更容易实现,而且在springboot中每个请求都会使用一个独立的线程,每个线程的ThreadLocal所对应的value都可以是不受影响的。

​ 到现在为止,我们获取信息的操作已经完成了,只需要向数据库验证账号密码,但是这不是我们这个token所需要讨论的内容。

​ 对于返回的信息,除了请求的正常返回,还需要携带一些信息在响应header中:

  • token:首先需要将tToken+sToken + step,作为token返回,这里需要使用AESKey加密。
  • random-server:是ASEKey的一部分,用RAS加密后返回给前端,前端获取后可以组成AESkey解密token。
  • flag:这是一个标志位,因为在上面的逻辑里没提到,我会在后面的文章里详细说明。
登出接口切面 和 正常请求接口切面

​ 对于登出接口和正常请求接口的切面,他们的判断逻辑是相同的,只是操作逻辑会有不同,所以放在一起来说。

​ 对于这里的判断逻辑,首先会获取请求的header,这里是获取token。在这里的token中会发现,token是被AES加密的,所以我们需要知道,这个token对应的ASEKey是什么,那么我们是不是还需要从header中获取AESKey呢?

​ 我们不应该相信前端传来的信息!所以我们希望直接获取到这个AESKey,这也是在上面出现了一个flag位的原因。我们会在登录中,将信息存储到数据库中,我们会设置两个key对应的value:

  1. flag->token
  2. flag->AESKey

​

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1002592.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号