18.token刷新拦截器

news2024/11/15 23:31:02

问题

上一篇博客中提到使用redis来存用户的登录信息,解决了session不共享问题。

在拦截器中,重新设置了用户信息的有效期,保证只要用户一直请求就永不过期。但是并不是每个请求都会经过拦截器的(因为登录拦截器,不是每个请求都需要验证登录),那么就会导致用户比如一直在访问不会经过拦截器的请求,突然就会提示用户未登录,这就不合适了。

解决

新添加一个拦截器,专门用于拦截所有请求,只用于获取token,获取用户信息,将用户信息放入redis,刷新token的有效期,放行。

小提示

 redis客户端工具可以查看key的有效期。

实现思路图

 刷新token的拦截器

package com.xkj.org.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.xkj.org.dto.UserDTO;
import com.xkj.org.utils.RedisConstants;
import com.xkj.org.utils.SystemConstants;
import com.xkj.org.utils.UserHolder;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Struct;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class RefreshTokenInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //从请求头中获取用户登录的token
        String token = request.getHeader("authorization");
        if(StrUtil.isBlank(token)) {
            //直接放行,不做处理
            return true;
        }

        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(RedisConstants.LOGIN_USER_KEY + token);
        //entries不会为null,只需要判断是否为空map即可
        if(entries.isEmpty()) {
            //直接放行,不做处理
            return true;
        }
        //将map转成UserDTO
        UserDTO userDTO = BeanUtil.fillBeanWithMap(entries, new UserDTO(), false);
        //将UserDTO存入ThreadMap中
        UserHolder.saveUser(userDTO);
        //刷新token的有效期
        stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY + token, RedisConstants.LOGIN_USER_TTL,
                TimeUnit.MINUTES);
        //放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserHolder.removeUser();
    }
}

登录拦截器

package com.xkj.org.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.xkj.org.dto.UserDTO;
import com.xkj.org.utils.RedisConstants;
import com.xkj.org.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        UserDTO user = UserHolder.getUser();
        if(ObjectUtil.isNull(user)) {
            //未登录,拦截
            response.setStatus(401);
            return false;
        }
        //放行
        return true;
    }

}

拦截器配置类

package com.xkj.org.config;

import com.xkj.org.interceptor.LoginInterceptor;
import com.xkj.org.interceptor.RefreshTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加token刷新拦截器,用户拦截所有请求,获取header中token,获取redis中的用户信息,存入ThreadLocal中,刷新token的有效期
        //设置order,优先执行,值越大优先级越低
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);

        //添加登录验证拦截器,排除一些不需要拦截的url
        registry.addInterceptor(new LoginInterceptor())
        .excludePathPatterns(
                "/user/code",
                "/user/login",
                "/blog/hot",
                "/shop/**",
                "/shop-type/**",
                "/upload/**",
                "voucher/**"

        ).order(1);
    }
}

ThreadLocal使用

package com.xkj.org.utils;

import com.xkj.org.dto.UserDTO;

public class UserHolder {

    private static final ThreadLocal<UserDTO> t1 = new ThreadLocal<>();

    public static void saveUser(UserDTO userDTO) {
        t1.set(userDTO);
    }

    public static UserDTO getUser() {
        return t1.get();
    }

    public static void removeUser() {
        t1.remove();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多个文件上传

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

【书生大模型实战营】LMDeploy 量化部署进阶实践

LMDeploy 量化部署进阶实践 【书生大模型实战营】LMDeploy 量化部署进阶实践任务环境将大模型封装为API接口服务以命令行形式连接API服务器以Gradio网页形式连接API服务器 LMDeploy Lite和InternLMkv cacheW4A16 模型量化和部署W4A16 量化 KV cacheKV cache 量化 LMDeploy与Int…

【JavaEE】MyBatis 实战指南:从 JDBC 到高效数据库操作的进阶教程

目录 MyBatis 操作数据库JDBC 操作⽰例回顾什么是MyBatis?MyBatis⼊⻔1. 准备⼯作2. 配置数据库连接字符串3. 写持久层代码4. 单元测试使用MyBatis可能遇到的问题 MyBatis的基础操作打印⽇志参数传递增(Insert)返回主键 删(Delete)改(Update)查(Select)起别名结果映射开启驼峰…

vue使用高德获取当前地区天气

1、收件箱 | 高德控制台 (amap.com) 首先打开高德开放平台注册一下 2、创建一个应用获取到key后面获取天气的时候 请求接口的时候会用到key 2.1.1 创建应用的时候注意类型选成天气 2.1.2 创建完成之后就点添加key 然后选择web服务就行 3、可以调取天气接口 天气查询-基础 API…

https握手过程详解

https握手过程详解 上一篇《HTTPS通讯全过程》中https握手过程实际上还有更多的细节&#xff0c;为什么会这样设计呢&#xff1f;是因为一开始将握手过程时&#xff0c;吧步骤说的太详细会导致更难理解惹。所以我就先在上一篇把部分细节忽略&#xff0c;把原来几步的过程先简化…

洛杉物理服务器怎么样?

洛杉矶作为美国科技和互联网的重要中心&#xff0c;物理服务器的质量通常非常高&#xff0c;可以提供卓越的性能、强大的安全性、多样的配置选项和专业的服务支持。以下是对洛杉物理服务器的详细介绍。 1. 优质的性能 稳定的网络连接&#xff1a;洛杉矶物理服务器位于先进的数据…

CASS11时空版 全新升级支持多版本CAD软件下载License使用

南方数码地形地籍成图软件CASS&#xff0c;经过二十余年的发展&#xff0c;市场和技术积累丰厚&#xff0c;用户遍及国内外测绘地理信息相关行业。软件销量和市场占有率持续领先&#xff0c;是业内应用广&#xff0c;服务优的软件品牌。 南方数码深刻理解信息化测绘的内…

合宙LuatOS生成毫秒级时间戳

合宙Luatos - os操作 os.time()生成时间戳的精度只能达到秒级&#xff0c;在很多联网应用中需要毫秒级的时间戳。 经查看LuatOS-SOC接口文档&#xff0c;发现了解决办法。 socket - 网络接口文档 通过文档&#xff0c;我们只要获取当前数&#xff0c;然后把毫秒数与os.time(…

【C语言】:字符和字符串中的字符比较

1.入门 当我们想要一个字符和字符串中的某个字符进行比较时&#xff0c;可以直接用“”进行比较。 为什么可以用“”&#xff1f; 因为字符是存放在常量区&#xff0c;字符变量的值是固定的&#xff0c;字符之间的比较&#xff0c;本质上是对字符的ASCII比较。ASCII_百度百科…

FinalData-绿色便携免安装数据恢复软件 下载

下载地址(资源制作整理不易&#xff0c;使用需付费&#xff0c;不能接受请勿浪费时间下载)&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/17CH5tkSc2qAj-6FuGvfb9Q?pwdvyze 提取码&#xff1a;vyze

基于Java语言的能源管理系统-水电气热油数据采集系统

基于Java语言的能源管理系统-水电气热油数据采集系统 介绍 适用于高能耗企业、建筑、工厂、园区的水、电、气、热、油、空压机等能源数据采集、分析、报表&#xff1b; 基于SpringCloud的能源管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管…

string模拟

本章准备对string模拟进行讲解&#xff0c;以下是string的学习网址&#xff1a; string - C Reference (cplusplus.com) string本质可以理解为储存char类型的顺序表&#xff0c;其中string的迭代器用一个char*就可以解决。所以string类成员变量如下&#xff1a; 这里用了一个命…

PumpkinRaising靶机

端口扫描 目录扫描 访问80端口&#xff0c; 在页面上面发现提到了一个Jack&#xff0c;可能是一个用户名 f12查看源码 找到一个页面 拼接访问 查看源码 发现一个注释 解密 是一个目录 /scripts/spy.pcap 访问&#xff0c;自动下载了一个文件 wireshark打开流量包 找到第一个s…

Element plus部分组件样式覆盖记录

文章目录 一、el-button 样式二、Popconfirm 气泡确认框三、Popover 气泡卡片四、Checkbox 多选框五、Pagination 分页六、Form 表单七、Table 表格 一、el-button 样式 html&#xff1a; <el-button class"com_btn_style">button</el-button>样式覆盖…

端口隔离 Port isolation 华为交换机配置端口隔离

Port isolation 什么是端口隔离 如果用户想进行二层隔离&#xff0c;用户可以将不同的端口加入不同的VLAN&#xff0c;但这样会浪费有限的VLAN资源。采用端口隔离功能&#xff0c;可以实现同一VLAN内端口之间的隔离。用户只需要将端口加入到隔离组中&#xff0c;就可以实现隔离…

hyper-v连接显卡,hyper-v使用显卡能力、Hyper-V显卡虚拟化VMGpu设置

hyper-v连接显卡&#xff0c;hyper-v使用显卡能力、Hyper-V显卡虚拟化VMGpu设置 现在越来越多的软件在使用时&#xff0c;都会调用GPU获得更好的使用效果。如&#xff1a;浏览器的硬件加速模式。由于Nvidia和AMD都屏蔽了家用显卡虚拟化技术&#xff0c;常用的虚拟机也无法对显卡…

交互式散点图,快速提升你的PPT观赏性|每日科研绘图·24-08-17

一、散点图基础概念 散点图是一种非常直观且功能强大的图表&#xff0c;用于探索和展示两个数值变量之间的相关性。这种图表通过在二维平面上绘制数据点&#xff0c;使得观察者能够一眼看出变量间的潜在联系。 1-1&#xff1a;散点图的构成 X轴&#xff08;横轴&#xff09;&…

电话语音机器人优势很多

智能语音机器人近年来备受关注&#xff0c;受到很多个人或是企业的青睐&#xff0c;其广泛受到欢迎归因于智能语音机器人对电话销售提供了极大的帮助&#xff0c;其可以完美替代人工进行电销外呼服务&#xff0c;不间断的工作&#xff0c;不带有任何情绪色彩&#xff0c;且能实…

Hive:大数据时代的SQL魔法师

时间&#xff1a;2024年08月17日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频地址&#xff1a;https://xima.tv/1_ZRh54d?_sonic0 希望大家帮个忙&#xff01;如果大家有工作机会&#xff0c;希望帮小蒋内推一下&#x…

半岛体存储器常见类型简介

前言 个人邮箱&#xff1a;zhangyixu02gmail.com在学习 ESP32 的存储器结构时&#xff0c;发现 DRAM 是 Data RAM 而非 Dynamic RAM&#xff0c;IRAM 是 Instruction RAM 而非 Internal RAM 。突然发现自己对于这一块的知识还比较混乱&#xff0c;因此查阅相关资料进行学习整理…