当前位置: 首页 > news >正文

redis优化token校验主动失效

  1. 场景:在普通的token颁发和校验中 当用户发现自己账号和密码被暴露了时修改了登录密码后旧的token仍然可以通过系统校验直至token到达失效时间,这肯定是不安全的,所以系统需要token主动失效的一种能力
  2. 解决方案:我们可以使用redis来实现redis主动失效的的功能
  3. 需求实现逻辑:
    1. 在每次用户登录后颁发token的同时往redis数据库中存储一份颁发给用户的token
    2. 每次每次用户请求时除了解析token外还需要查询redis中是否有当前token有则校验通过,没有则校验失败
    3. 每次用户修改密码后删除redis中当前用所携带的token,从而使旧token无法通过token校验
  4. 代码实现
    1. pom.xml中添加redis坐标
<!--redis坐标-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
2. 配置文件application.yml中配置redis相关信息
spring:
  data:
    redis:
      host: redis所在的ip,本机的redis服务填localhost
      port: redis服务端口,默认6379
      password: redis中设置的密码,没有就不需要


3. 颁发token时往redis中存储token
//UserController中添加私有属性stringRedisTemplate并实例化
@Autowired
private StringRedisTemplate stringRedisTemplate;

//登录接口中把token存到redis 过期时间3小时
stringRedisTemplate.opsForValue().set(token,token,3, TimeUnit.HOURS);
4. 登录时校验是否redis中有当前token
package org.example.intercopters;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.utils.JwtUtil;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

@Component //注册拦截器 将其放入ioc容器中
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate redisTemplate;
    //创建登录身份校验拦截器
    @Override  //请求开始前触发的拦截方法
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token = request.getHeader("Authorization");
        //去除token的前缀标记"Bearer "
        var newToken = token.contains("Bearer ")?token.substring("Bearer ".length()):token;

        try {
            **//从redis获取相同的token
            String redisToken = redisTemplate.opsForValue().get(newToken);
            if(redisToken == null){
                //redis失效
                throw new RuntimeException("token失效");
            }**
            Map<String, Object> claims = JwtUtil.parseToken(token);

            //把用户信息存储到ThreadLocal中,tomcat会在每次接口请求时创建一个线程 而ThreadLocal中存储的数据是线程安全的
            ThreadLocalUtil.set(claims);

            //放行
            return true;

        } catch (Exception e) {
            //设置响应状态码
            response.setStatus(401);
            //设置响应字符集和响应内容
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html; charset=UTF-8");
            String errorMessage = "未登录";
            response.getWriter().write("{\"error\": \"" + errorMessage + "\"}");
            //不放行
            return false;
        }
    }
    @Override  //请求完成后触发的拦截方法
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清空ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }
}
5. 修改密码后删除redis中的token
//修改密码接口中删除redis中对应的token
ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
operations.getOperations().delete(newToken);
  1. 在本地开发中如果使用本地redis每次开发前还得去启动本地redis,就很麻烦,如果你有一个云服务器就可以本地连云服务器redis就不用每次去启动redis了,下面是实现教程
    1. https://blog.csdn.net/weixin_45695974/article/details/123244011

相关文章:

  • 基于UDP的网络聊天室
  • rtt的io设备框架面向对象学习-内部调用流程
  • Linux相关命令(2)
  • jackson:JSON字符串(String)类型的成员序列化和反序列化
  • 【运维笔记】VM 记录一次centos虚拟机和宿主机之间ping不通的问题
  • 基于 HBase Phoenix 构建实时数仓(5)—— 用 Kafka Connect 做实时数据同步
  • 【Redis知识点总结】(七)——缓存雪崩、缓存穿透、缓存击穿、Redis高级用法
  • ReaLTaiizor开源.NET winform控件库学习使用
  • Redis 不再“开源”,对中国的影响及应对方案
  • docker仓库登录及配置insecure-registries的方法
  • python基础——数据容器总结、通用方法和相互转换
  • (一)Linux+Windows下安装ffmpeg
  • 【Golang星辰图】创造美丽图表,洞察数据:解析Go语言中的数据可视化和数据分析库
  • 一次完整的 HTTP 请求所经历的步骤
  • node.js中常用的命令及示例
  • 「Linux系列」Shell 流程控制if-else/for循环/While循环/until循环/case语句/跳出循环break、continue
  • How to install mongodb on redhat 7.7
  • 《论文阅读》带边界调整的联合约束学习用于情感原因对提取 ACL 2023
  • IDEA 下载依赖包源码报错 Cannot download sources Sources not found for:XXX
  • 云原生相关知识
  • 名帅大挪移提前开启,意属皇马的阿隆索会是齐达内第二吗
  • 新买宝马竟是“维修车”,男子发视频维权被4S店索赔100万
  • 最快3天开通一条定制公交线路!上海推出服务平台更快响应市民需求
  • 范志毅跨界归来做青训,探索中国足球人才培养新模式
  • 罗氏制药全新生物制药生产基地投资项目在沪启动:预计投资20.4亿元,2031年投产
  • 司法部:建立行政执法监督企业联系点,推行行政执法监督员制度