建设公司网站应有哪些功能,生活分类信息网站大全,wordpress 制作侧边栏,网站 文件夹结构文章目录 1、登出的实现思路2、集成Redis3、认证成功处理器4、退出成功处理器5、修改token校验过滤器6、调试 1、登出的实现思路
这是目前的token实现图#xff1a; 因为JWT的无状态#xff0c;服务端无法在使用过程中主动废止某个 token#xff0c;或者更改 token 的权限… 文章目录 1、登出的实现思路2、集成Redis3、认证成功处理器4、退出成功处理器5、修改token校验过滤器6、调试 1、登出的实现思路
这是目前的token实现图 因为JWT的无状态服务端无法在使用过程中主动废止某个 token或者更改 token 的权限。也就是说目前一旦 JWT 签发了就只能等它到过期时间才能作废即使用户已经退出登录。想实现登出可以引入Redis 此时关于token的校验逻辑就变成了 总结就是 ① 登陆成功之后把生成JWT存到redis中(同时设置key的TTL和JWT自身过期时间一样) ② 用户退出时从redis中删除该token ③ 用户每次访问时先校验jwt是否合法如果合法再从redis里面取出logintoken:jwt判断这个jwt还存不存在如果不存在就说是用户已经退出登录了 2、集成Redis
引入redis的依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency
配置连接信息
spring:redis:host: localhostport: 6379database: 0password: 666666
注入redis操作对象的依赖
Resource
private StringRedisTemplate stringRedisTemplate;
PS我们没有创建RedisTemplate对象对应的bean但这个bean却在我们引入依赖后自动加入到了Spring容器中即自动装配。
3、认证成功处理器
修改前一节的认证成功处理器在向客户端发放token的同时存入rediskey的过期时间和token自身过期时间一致。
...Resource
private StringRedisTemplate stringRedisTemplate;
....
stringRedisTemplate.opsForValue().set(logintoken:token,objectMapper.writeValueAsString(authentication),30, TimeUnit.MINUTES);
我这里key设置成了字符串logintoken:后跟token值value则直接序列化认证对象authentication。 注意过期时间和jwt的过期时间保持一致jwt过期时间可查看下创建jwt时的withExpiresAt方法。
4、退出成功处理器
添加退出成功处理器退出后清除redis里存的token
/*** 退出成功处理器用户退出成功后执行此处理器*/
Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {//使用此工具类的对象进行序列化操作Resourceprivate ObjectMapper objectMapper;Resourceprivate StringRedisTemplate stringRedisTemplate;Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {//从请求头中获取Authorization信息String authorization request.getHeader(Authorization);//如果授权信息为空返回前端if(nullauthorization){response.setCharacterEncoding(UTF-8);response.setContentType(application/json;charsetutf-8);HttpResult httpResultHttpResult.builder().code(-1).msg(token不能为空).build();PrintWriter writer response.getWriter();writer.write(objectMapper.writeValueAsString(httpResult));writer.flush();return;}//如果Authorization信息不为空去掉头部的Bearer字符串String token authorization.replace(Bearer , );//redis中删除token这是关键点stringRedisTemplate.delete(logintoken:token);response.setCharacterEncoding(UTF-8);response.setContentType(application/json;charsetutf-8);HttpResult httpResultHttpResult.builder().code(200).msg(退出成功).build();PrintWriter writer response.getWriter();writer.write(objectMapper.writeValueAsString(httpResult));writer.flush();}
}
在安全配置类中配置用户成功退出处理器
Resource
private MyLogoutSuccessHandler myLogoutSuccessHandler;....
http.logout().logoutSuccessHandler(myLogoutSuccessHandler);
http.csrf().disable(); //禁用跨域请求保护 要不然logout不能访问
5、修改token校验过滤器
修改上一节的token校验器JWTCheckFilter不再只校验token的合法性合法时还要校验服务端redis中是否有相应数据以判断是否已经登出。
Resource
private StringRedisTemplate stringRedisTemplate;//从redis中获取token
String tokenInRedis stringRedisTemplate.opsForValue().get(logintoken: jwtToken);
if(!StringUtils.hasText(tokenInRedis)){printFront(response, 用户已退出请重新登录);return;
}
完整 6、调试
登录下先 得到token 此时服务端redis 登出时token为空 登出时token错误 正常登出 此时拿登出的token再请求接口