阅读本文约“2.5分钟”
本文开发环境是SpringBoot2.X版本。
对于系统而言(这里多指管理系统或部分具备登录登出功能的系统),登录登出是一个类权限验证的过程,现在一般是以token进行校验,即用户输入登录信息,系统对其进行判断,如果信息准确放行并下发一个token值到用户的cookie中,接下来用户的每一个操作(对系统的读写操作等),后台系统都会验证token的准确性还有存在性,以此确定用户的登录信息正常,登出时就清除token,如下图所示。
那么可能意味着,我们对每一个Controller层的方法都需要加一个token验证的代码段,这是非常浪费时间的流程。
那么SpringBoot中就有非常方便我们处理这个同意验证的方式,我们可以通过切面Aspect,通过定义切面类,并使用Poincut指定切入点,比如某字段开头的全部Controller类的方法,并在Before之前进行验证,我们就进行写一个验证说实现,即查询Cookie中是否存在token字段,token字段与下发的原始token是否相同,进行验证,如果不对,就抛出自定义的验证异常如AuthorizeException类(其继承RuntimeException),然后在定义了一个捕获异常的handler,对验证异常的返回做统一的数据返回格式。
如下流程图所示。
还有一点,我们下发的token是要存放在哪里呢?这里的token是随机的,暂时性的(即存在时间限制,用户不可能永远有权限访问,存在过期时间),对于单应用系统可以存放在系统内存中,如设定一个全局的set等,但是现在大部分架构要考虑分布式,我推荐存放在redis中,并设定时间,这样Aspect中的方法就仅仅多了去redis中查询的操作,登录时也仅需将生成的token存放到redis中。
这种方式很适合分布式应用,我在个人的开源项目中就是使用了这种方式,如果有兴趣,大家可以去看看源码MintSells
https://github.com/UncleCatMySelf/MintSells
项目的开发文档也比较详细。