JWT实现登陆认证及Token自动续期
今天就来讲讲认证功能的技术选型及实现。技术上没啥难度当然也没啥挑战,但是对一个原先没写过认证功能的菜鸡甜来说也是一种锻炼吧
技术选型
要实现认证功能,很容易就会想到JWT或者session,但是两者有啥区别?各自的优缺点?应该Pick谁?夺命三连
区别
基于session和基于JWT的方式的主要区别就是用户的状态保存的位置,session是保存在服务端的,而JWT是保存在客户端的
认证流程
基于session的认证流程
- 用户在浏览器中输入用户名和密码,服务器通过密码校验后生成一个session并保存到数据库
- 服务器为用户生成一个sessionId,并将具有sesssionId的cookie放置在用户浏览器中,在后续的请求中都将带有这个cookie信息进行访问
- 服务器获取cookie,通过获取cookie中的sessionId查找数据库判断当前请求是否有效
基于JWT的认证流程
- 用户在浏览器中输入用户名和密码,服务器通过密码校验后生成一个token并保存到数据库
- 前端获取到token,存储到cookie或者local storage中,在后续的请求中都将带有这个token信息进行访问
- 服务器获取token值,通过查找数据库判断当前token是否有效
优缺点
- JWT保存在客户端,在分布式环境下不需要做额外工作。而session因为保存在服务端,分布式环境下需要实现多机数据共享
- session一般需要结合Cookie实现认证,所以需要浏览器支持cookie,因此移动端无法使用session认证方案
安全性
- JWT的payload使用的是base64编码的,因此在JWT中不能存储敏感数据。而session的信息是存在服务端的,相对来说更安全
如果在JWT中存储了敏感信息,可以解码出来非常的不安全
性能
- 经过编码之后JWT将非常长,cookie的限制大小一般是4k,cookie很可能放不下,所以JWT一般放在local storage里面。并且用户在系统中的每一次http请求都会把JWT携带在Header里面,HTTP请求的Header可能比Body还要大。而sessionId只是很短的一个字符串,因此使用JWT的HTTP请求比使用session的开销大得多
一次性
无状态是JWT的特点,但也导致了这个问题,JWT是一次性的。想修改里面的内容,就必须签发一个新的JWT
- 无法废弃
一旦签发一个JWT,在到期之前就会始终有效,无法中途废弃。若想废弃,一种常用的处理手段是结合redis - 续签
如果使用JWT做会话管理,传统的cookie续签方案一般都是框架自带的,session有效期30分钟,30分钟内如果有访问,有效期被刷新至30分钟。一样的道理,要改变JWT的有效时间,就要签发新的JWT。最简单的一种方式是每次请求刷新JWT,即每个HTTP请求都返回一个新的JWT。这个方法不仅暴力不优雅,而且每次请求都要做JWT的加密解密,会带来性能问题。另一种方法是在redis中单独为每个JWT设置过期时间,每次访问时刷新JWT的过期时间
选择JWT或session
我投JWT一票,JWT有很多缺点,但是在分布式环境下不需要像session一样额外实现多机数据共享,虽然seesion的多机数据共享可以通过粘性session、session共享、session复制、持久化session、terracoa实现seesion复制等多种成熟的方案来解决这个问题。但是JWT不需要额外的工作,使用JWT不香吗?且JWT一次性的缺点可以结合redis进行弥补。扬长补短,因此在实际项目中选择的是使用JWT来进行认证
功能实现
JWT所需依赖
JWT工具类
说明:
- 生成的token中不带有过期时间,token的过期时间由redis进行管理
- UserTokenDTO中不带有敏感信息,如password字段不会出现在token中
Redis工具类
RedisTemplate简单封装
业务实现
登陆功能
说明:
- 判断用户名密码是否正确
- 用户名密码正确则生成token
- 将生成的token保存至redis
登出功能
将对应的key删除即可
更新密码功能
说明:
更新用户密码时需要重新生成新的token,并将新的token返回给前端,由前端更新保存在local storage中的token,同时更新存储在redis中的token,这样实现可以避免用户重新登陆,用户体验感不至于太差
其他说明
- 在实际项目中,用户分为普通用户和管理员用户,只有管理员用户拥有删除用户的权限,这一块功能也是涉及token操作的,但是我太懒了,demo工程就不写了
- 在实际项目中,密码传输是加密过的
拦截器类
说明:
拦截器中主要做两件事,一是对token进行校验,二是判断token是否需要进行续期
token校验:
- 判断id对应的token是否不存在,不存在则token过期
- 若token存在则比较token是否一致,保证同一时间只有一个用户操作
token自动续期: 为了不频繁操作redis,只有当离过期时间只有30分钟时才更新过期时间
拦截器配置类
写在最后
若有纰漏不足,欢迎指出
点个赞在走
原文链接:https://juejin.cn/post/6932702419344162823
__EOF__

本文链接:https://www.cnblogs.com/dusucyy/p/16467493.html
关于博主:编程小萌新一名,希望从今天开始慢慢提高,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~