【SpringSecurity】十二、集成JWT搭配Redis实现退出登录

文章目录

  • 1、登出的实现思路
  • 2、集成Redis
  • 3、认证成功处理器
  • 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的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置连接信息:

spring:
  redis:
    host: localhost
    port: 6379
    database: 0
    password: 666666

注入redis操作对象的依赖:

@Resource
private StringRedisTemplate stringRedisTemplate;

(PS:我们没有创建RedisTemplate对象对应的bean,但这个bean却在我们引入依赖后自动加入到了Spring容器中,即自动装配。)

3、认证成功处理器

修改前一节的认证成功处理器,在向客户端发放token的同时存入redis,key的过期时间和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 {
    //使用此工具类的对象进行序列化操作
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //从请求头中获取Authorization信息
        String authorization = request.getHeader("Authorization");
        //如果授权信息为空,返回前端
        if(null==authorization){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=utf-8");
            HttpResult httpResult=HttpResult.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;charset=utf-8");
        HttpResult httpResult=HttpResult.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再请求接口:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/102433.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python爬虫】批量识别pdf中的英文,自动翻译成中文上

不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。本文提供批量识别pdf中英文的方法,后续文章实现自…

Python3 条件控制

Python3 条件控制 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 代码执行过程&#xff1a; if 语句 Python中if语句的一般形式如下所示&#xff1a; if conditi…

(超简单)将图片转换为ASCII字符图像

将一张图片转换为ASCII字符图像 原图&#xff1a; 效果图&#xff1a; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileWriter; import java.io.IOException;public class ImageToASCII {/*** 将图片转换为A…

Java“牵手”1688商品列表数据,关键词搜索1688商品数据接口,1688API申请指南

1688商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取1688商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问1688商城的网页来获取商品详情信息。以下是两种常用方法的介绍&…

Python教程(12)——Python数据结构集合set介绍

集合 创建集合访问集合删除集合修改集合元素添加集合元素删除集合元素 集合运算&#xff1a;并集&#xff08;Union&#xff09;交集&#xff08;Intersection&#xff09;差集&#xff08;Difference&#xff09;对称差集&#xff08;Symmetric Difference&#xff09; 集合的…

嵌入式学习之进程

1.进程间通信概述 UNIX系统IPC是各种进程通信方式的统称。 2.管道通信原理 特点&#xff1a; 1.它是半双工的&#xff08;即数据只能在一个方向上流动&#xff09;&#xff0c;具有固定的读端和写端。 2.它只能用于具有亲缘关系的进程之间通信&#xff08;也是父子进程或者…

基于springboot跟redis实现的排行榜功能(实战)

概述 前段时间&#xff0c;做了一个世界杯竞猜积分排行榜。对世界杯64场球赛胜负平进行猜测&#xff0c;猜对1分&#xff0c;错误0分&#xff0c;一人一场只能猜一次。 1.展示前一百名列表。 2.展示个人排名(如&#xff1a;张三&#xff0c;您当前的排名106579)。 一.redis so…

K8S访问控制------认证(authentication )、授权(authorization )、准入控制(admission control )体系

一、账号分类 在K8S体系中有两种账号类型:User accounts(用户账号),即针对human user的;Service accounts(服务账号),即针对pod的。这两种账号都可以访问 API server,都需要经历认证、授权、准入控制等步骤,相关逻辑图如下所示: 二、authentication (认证) 在…

23062day6

作业&#xff1a;将dict.txt导入到数据库中。 方法1&#xff1a;创建shell脚本&#xff0c; 调用指令创建数据库和表格&#xff0c;使用循环在循环中用数组存储dict.txt的内容并插入表格中。 方法2&#xff1a;在终端创建数据库和表格&#xff0c;将dict.txt中的内容手动输入…

带纽扣电池产品出口澳洲安全标准,纽扣电池IEC 60086认证

澳大利亚政府公布了《消费品&#xff08;纽扣/硬币电池&#xff09;安全标准》和《消费品&#xff08;纽扣/硬币电池&#xff09;信息标准》。届时出口纽扣/硬币电池以及含有纽扣/硬币电池产品到澳大利亚的供应商&#xff0c;必须遵守这些标准中的要求。 一、 安全标准及信息标…

db2迁移至oracle

1.思路 &#xff08;1&#xff09;用java连接数据库&#xff08;2&#xff09;把DB2数据导出为通用的格式如csv&#xff0c;json等&#xff08;3&#xff09;导入其他数据库&#xff0c;比如oracle&#xff0c;mongodb。这个方法自由发挥的空间比较大。朋友说他会用springboot…

yolov5的pytorch配置

1. conda create -n rdd38 python3.82、pip install torch1.8.0 torchvision0.9.0 torchaudio0.8.0 -f https://download.pytorch.org/whl/cu113/torch_stable.html -i https://pypi.tuna.tsinghua.edu.cn/simple 3、conda install cudatoolkit10.2

在抖音中使用语聚AI,实现自动回复用户视频评论、私信问答

您可以通过集简云数据流程&#xff0c;将语聚AI助手集成到抖音视频评论、抖音私信&#xff0c;实现自动回复用户视频评论、私信问答&#xff0c;大大提升账号互动与运营效率。 效果如下&#xff1a; 自动化流程&#xff1a; ● 抖音普通号评论对接语聚AI&#xff08;点击可一…

CSS 一个好玩的卡片“开卡效果”

文章目录 一、用到的一些CSS技术二、实现效果三、代码 一、用到的一些CSS技术 渐变 conic-gradientbox-shadowclip-path变换、过渡 transform、transition动画 animation keyframes伪类、伪元素 :hover、::before、::after …绝对布局。。。 clip-path 生成网站 https://techb…

聊聊每日站会

这是鼎叔的第七十四篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本专栏和微信公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。 每日站会是一线敏捷团队自己的会议&#xff0c;快速同步成员为达成迭代目标所…

TensorRT来加速YOLO v5推理与检测

TensorRT来加速YOLO v5推理与检测 文章目录 TensorRT来加速YOLO v5推理与检测TensorRT简介一、TensorRT安装1. 电脑基础环境2. 查看 cuda 版本3. 安装TensorRT4. 验证TensorRT 二、YOLO v5模型导出函数1.onnx 模型导出&#xff08;def export_onnx&#xff08;&#xff09;函数…

【小吉送书—第一期】Kali Linux高级渗透测试

文章目录 &#x1f354;前言&#x1f6f8;读者对象&#x1f388;本书资源&#x1f384;彩蛋 &#x1f354;前言 对于企业网络安全建设工作的质量保障&#xff0c;业界普遍遵循PDCA&#xff08;计划&#xff08;Plan&#xff09;、实施&#xff08;Do&#xff09;、检查&#x…

2023-09-02 LeetCode每日一题(最多可以摧毁的敌人城堡数目)

2023-09-02每日一题 一、题目编号 2511. 最多可以摧毁的敌人城堡数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个长度为 n &#xff0c;下标从 0 开始的整数数组 forts &#xff0c;表示一些城堡。forts[i] 可以是 -1 &#xff0c;0 或者 1 &#xff0c;其中&…

C语言:截断+整型提升+算数转换练习

详情关于整型提升、算数转换与截断见文章&#xff1a; 《C语言&#xff1a;整型提升》 《C语言&#xff1a;算数转换》 一、代码一 int main() { char a -1; signed char b -1; unsigned char c -1; printf("%d %d %d", a, b, c); return 0; } 求…

Level-based Foraging 多智能体游戏仿真环境

游戏场景测试 参考链接&#xff1a; https://kgithub.com/semitable/lb-foraging