Spring MVC使用JWT做token验证
type
status
date
slug
summary
tags
category
icon
password
order
为什么选择JWT?
其最大的优点就是不需要存储介质,比如redis,JWT给我的感觉就是特别轻巧、简单便捷。
JWT是无状态的,token也都是一次性的,如果你想让这个token立即失效,是没办法的,只能等过期。
我也查阅了一下发现会有以下问题
注销登录等场景下token还有效,比如
  • 退出登录 (这个可以清除客户端cookie存储的token)
  • 修改密码 (由于我的JWT加的盐是包含了用户密码,所以这个问题也规避了)
  • 用户的帐户被删除/暂停 (这个正常的话直接删掉token,让用户重新登陆,JWT的话就需要在拦截器里验证token对应的用户时,判断下状态,ps:好像正常也需要每次判断下,我之前都给忽略了)
  • 用户由管理员注销 (这个。。。总不能注销时将用户加到一个集合里,拦截器里每次验证token时都判断下这集合吧,太不好了,真这样的话用Redis搞个黑名单)
综合来说,还是得利用其它介质辅助存储,比如Redis,还是给token加上了状态
JWT最适合的场景是不需要服务端保存用户状态的场景,比如如果考虑到 token 注销和 token 续签等场景的话,没有特别好的解决方案,大部分解决方案都给 token 加上了状态
JWT根据密钥进行加密组成一段字符串作为token,客户端每次请求时带上这个token,后端拦截器取到token后,会取出token包含的用户id等信息,然后用JWT解密验证是否有效即可。
notion image
jwt流程
JWT生成的token如下,可以看到由两个"."所隔开,一共是三部分
  • 第一部分称为头部(header), 声明类型以及加密的算法,然后base64加密得到
  • 第二部分称为载荷(payload),存放的就是有效信息,比如签发者,过期时间,标识等, 然后base64加密得到
  • 第三部分称为签证(signature),由 header +payload+secret(盐), 然后base64加密得到
要配合一些注解,拦截器的使用就不多说了,和下面这篇文章大概一样,最下面放下我所使用的代码,由于以前用的是Redis存储token,而我又不想直接删掉以前的代码,所以就让共存了,根据配置选择是Redis还是JWT。
https://loneking.cn/code/java/563
首先添加JWT的以来,在pom.xml中
TokenModel
JWT token操作类
Redis token操作类
TokenService
拦截器
 
Spring AOP实现Redis缓存方法haproxy配置参考