JWT认证
上
JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。
创建拦截器
配置拦截器
登录成功返回token
中
登录成功存储token
axios拦截器
请求拦截器
请求头添加token
响应拦截器
fetch全局配置
在所有使用fetch()方法请求的html文件中引入
下
方案介绍
JWT最后这部分工作是为了让退出登录和修改密码后token失效。对于token退出登录常见的解决方案有以下几种。
一、只在前端清除token,后端不做处理。这种方式使用的也很多,但是感觉并不合适,虽然前端清除了token但是在此之前如果的到token退出登录之后该token依旧可以使用。
二、白名单。认证通过之后将token存储在Redis中,退出登录之后将token从缓存中删除,每次请求判断该token是否在缓存中,在才能放行。
三、黑名单。退出登录之后将token存储在缓存中,每次请求判断token是否在缓存中,不在放行。
本项目选用黑名单的方案。
引入Redis依赖
Redis配置
UUID
在token中加入uuid用以唯一标识一个token,用以加入黑名单。所以实际上Redis中存储的是uuid而不是token。
退出登录
为了设置过期时间让redis自动删除,而不需要在设置定时任务,所以选择Redis中String数据类型,以键值对的形式存储,设置过期时间。
拦截器黑名单校验
前端退出登录
调用退出登录接口并且清除localstorage
感想
JWT这个功能模式非常固定,本来应该很快就能完成,但是还是花费了很多时间。有以下一些原因。前端除了vue页面使用axios请求之外还有html页面使用fetch,这要分别处理,并且要在所有使用fetch()方法的html页面引入fetch全局配置的js文件。之后是使token失效这一部分实现,可参考资料不多,很多博客只是描述思路,并没有实操,加上对Redis的了解不是很充分,在数据结构的选择,方法的使用方面出了一些错。然后是开始时前端设计比较混乱,对于用户和心理医生登录后在locastorage中的存储不相同,这在后续的使用中也使得代码逻辑变的混乱,还有一个问题是这样把用户的邮箱、手机号等隐私信息存储在localstorage中是否合适。基于这些问题的考虑,加上登录成功之后需要返回token对用户和心理医生登录成功之后的返回值做了统一,都使用userVO中的属性,包括id,用户名,头像这些不涉及隐私且在代码中经常使用的信息以及用于认证的token和用于区分角色的type。由于改了localstorage中存储的user,并取消了doctor所以更改了很多前端页面中的相关代码,这一部分也花了很多时间。
从这个功能的实现,我体会到了修改代码的不易,牵一发而动全身,之后这种会影响全局的代码和功能呢应该在最开始就实现,否则之后可能会影响整个系统,需要做很多的改动。在多处使用的部分也应该在最开始就慎重考虑、合理规划,如果发现有不合理的地方,就要尽早修改,时间越长,修改成本越高。