SpringBoot项目jwt生成token集成redis

2023-11-11

业务逻辑

1:用户登录,使用jwt生成token,
2:后端把这个token返回给前端,同时把这个token作为key存储在redis中,用户对象作为value。并设置一个过期时间。
3:用户以后每次访问都携带这个token,如果这个token在redis中存在就直接通过拦截器,不存在就使用jwt进行解析,如果jwt验证通过就认证通过,(这里有一个问题,就是如果这个用户已经离开了但是没有主动退出登录,导致redis中的token存在,而这个用户的token被别人盗用,那么由于我这个token设置的有效期是1天,即使所以风险还是很小的。那我这个时候又不要把token继续存到redis里面呢?是要存的,因为redis里的token存活时间是5小时,这个时间是在安全性和访问速度是取一个均衡。如果这个用户一天都没有离开token也会过期,那么它就要每次都进行jwt解析就无法利用redis的高效率了。还有就是即使存了,被别人盗用了token,也会在5小时之后过期,还是比较安全的。)如果jwt无法解析,无法通过拦截器。要求用户重新登录。登录后把token重新存入到redis中。
4:用户退出登录的时候把对应redis中的token删除。

部分代码实现

拦截器的配置

package com.dongmu.interceptor;

import com.dongmu.controller.LoginController;
import com.dongmu.dao.UserMapper;
import com.dongmu.pojo.User;
import com.dongmu.util.JwtUtil;
import com.dongmu.util.RedisUtil;
import com.dongmu.util.TokenUtil;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Component
public class Interceptor implements HandlerInterceptor {

    Logger logger = LoggerFactory.getLogger(Interceptor.class);


    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserMapper userMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {



        String token = TokenUtil.getToken(request);

        if (token==null){
            logger.info("未通过拦截器,身份验证失败了。");
            return false;
        }else {
            if (redisUtil.hget("token",token)!=null){
                //redis中存在就直接验证通过
                logger.info("通过拦截器,身份验证成功了。");
                return true;
            }else {
                try {
                    ///redis不存在就解析token,并把结果存到redis中
                    Claims claims = JwtUtil.parseJWT(LoginController.token_password, token);
                    User user = userMapper.selectByUserName((String) claims.get("username"));
                    redisUtil.hset("token",token,user,1000*60*60*5);
                    logger.info("通过拦截器,身份验证成功了。");
                    return true;
                }catch (Exception e){
                    logger.info("未通过拦截器,身份验证失败了。");
                    return false;
                }
            }

        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

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

配置到拦截器中

package com.dongmu.config;

import com.dongmu.interceptor.Interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class InteceptorConfig implements WebMvcConfigurer {

    @Autowired
    Interceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        String path = "/**";
        String excludePath="/login";
        String swaggerExcludePath[] = {"/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"};



//        HandlerInterceptor interceptor = new Interceptor();

        registry.addInterceptor(interceptor).addPathPatterns(path).excludePathPatterns(excludePath).excludePathPatterns(swaggerExcludePath);
    }
}

假如Reids服务关闭了,会存在什么问题?怎么解决?

如果redis服务关闭,就会导致spring一直重连redis,导致原来的服务不可用。
解决办法:
配置连接超时时间,设置短一点,同时包装redis封装工具类查询出现错误就返回null,
查询redis的时候如果返回null再查询数据库。
配置如下:

spring:
  redis:
    port: 6379
    host: 127.0.0.1
    database: 0
    password:
#      设置最大的连接超时时间
    timeout: 20ms
    lettuce:
      pool:
        #        最大连接池的数量,负数表示没有限制,默认为8
        max-active: 20
        #        连接池最大阻塞等待时间,负数表示没有限制
        max-wait: 1ms
        #        连接池最大连接数,默认为8
        max-idle: 8
        #        连接池最小连接数,默认为0
        min-idle: 0

添加的依赖:

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

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
<!--            <version>2.0</version>-->
        </dependency>

如果手动设置版本号,可能会出现依赖冲突,所以这里注释了。

如果想要只有一个用户登录怎么办?

那就把redis的key存为userId,第二个登录就会把第一个给替换掉。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot项目jwt生成token集成redis 的相关文章

随机推荐

  • python中scrapy框架使用flask框架编写api接口

    仅作参考 1在scrapy框架中编写api接口 在与setting py同级处新建api py 在该api py中编写一下代码 from flask import Flask import os app Flask name app rou
  • 【nvivo11plus教程】02_编码与节点

    1 对文档进行编码 1 建立节点 2 使用快速编码栏进行编码 3 将整个文件编码为一个代码 4 范围编码 5 在vivo中编码 6 使用节点昵称加快编码速度 2 取消 增加和查看编码 1 编码带 2 删除编码 3 查看编码邻近区 4 增加编
  • Pandas.read_excel详解

    文章目录 基础知识 语法 参数详解 index col 参数详解 header 参数详解 usecols 参数详解 dtype 其他参数 多表读取 顺带提一句如何用pandas写数据到excel 基础知识 pandas 可以读取多种的数据格
  • DLL load failed while importing win32gui: 找不到指定的程序

    pip install pywin32 226
  • 九、软考2014年上半年软件设计师易错题整理

    文章目录 错题1 错题2 错题3 错题4 错题5 错题6 错题7 错题8 错题9 错题10 错题11 错题12 错题13 错题14 错题15 错题16 错题17 错题18 错题19 错题20 专业英语 错题1 在CPU中 常用来为ALU执行
  • 字节跳动暑期实习生一面面经 大三

    身份 双非本科大三 大二从小程序开始学起前端 之后自学前端 自我介绍 了解box sizing吗 这里脑子没转 说了不太了解 面试官特别好 是会引导着你去回答问题的 了解盒模型吗 了解的 盒模型分为标准盒模型和IE盒模型 标准盒模型是包括m
  • reg型变量怎么赋值_FPGA的wire和reg类型变量

    1 wire型 网络类型变量表示结构实体 如门 之间的物理连接 网络类型变量不能存储值 而且它必须要受到驱动器 如门或连续赋值语句 如assign 的驱动 如果没有驱动器连接到网络类型变量上 则该变量就是高阻的 即值为Z 常用的网络类型变量
  • 完美国际服务器管理修改经验倍数,魔兽地图编辑问题--修改经验倍数

    呵呵 我来说说吧 1 选择英雄 提供了多种英雄选择方式包括技能 能量圈 双击选择英雄的方式 2 点击单位 出现文本提示 可以用在选择英雄的时候 单击想要选择的英雄 出现该英雄拥有技能的文本提示 3 同类物品不能同时携带 当单位身上已经携带该
  • git错误The TLS connection was non-properly terminated解决

    问题描述 在执行hexo d发布文章时候 出现错误 error fatal unable to access https github com huanyouchen huanyouchen github io git gnutls han
  • java OA 系统开发二:数据库设计之oa数据库设计

    一 概述 oa数据库表设计 用户信息表 机构信息表 部门信息表 员工考勤 我的便签 消息管理 邮件管理 登入日志 操作日志 考勤标准 文档类型 考勤统计 我的日程 部门日程表 用户角色中间表 角色管理 角色菜单中间表 菜单父节点 菜单子节点
  • 这篇文章完美的解释了为什么有人不喜欢Spinner,当它在某些主题下出来的非常丑

    这篇文章完美的解释了为什么有人不喜欢Spinner 当它在某些主题下出来的非常丑 http www jcodecraeer com a anzhuokaifa androidkaifa 2015 0105 2264 html
  • 华为OD机试真题 Java 实现【最远足迹】【2022Q4 100分】,附详细解题思路

    目录 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 一 题目描述 某探险队负责对地下洞穴进行探险 探险队成员在进行探险任务时 随身携带的记录
  • Java基础小测总结

    1 非抽象实现接口后 实现接口中方法的原则 两同两小一大原则 方法名相同 参数类型相同 子类返回类型小于等于父类方法返回类型 子类抛出异常小于父类方法抛出异常 子类访问权限大于等于父类方法访问权限 2 volatile关键字 被volati
  • 踩坑 calendar.getActualMaximum(calendar.DAY_OF_MONTH)函数

    当使用calendar getActualMaximum calendar DAY OF MONTH 获取每月最后一天时或者获取当季的最后一天时 会出现在二月的时候获取的不准确的情况 问题出现原因 代码没有动过 之前一直是使用这个时间函数来
  • 如何使用数字孪生和人工智能优化制造

    将数字孪生 digital twin 与人工智能 AI 相结合 可以减少甚至消除产品制造过程中的 臆测 几率 降低因不合理的想法实施带来的损失 那么 到底什么是数字孪生 它又是如何使现实中的生产过程变得更加高效的 CXO TALK采访了西门
  • 白嫖 IBM LinuxOne 服务器教程

    白嫖 IBM LinuxOne 教程 1 介绍 1 1前言 LinuxONE Community Cloud是IBM联合Marist大学为学生提供的用于测试应用程序和网站的平台 提供长达120天的免费VPS 温馨提醒 这个 VPS 是 S3
  • 游戏中关于跳跃的函数图像的推导以及应用

    跳跃应该是游戏开发中一个最常见的功能之一 实现的方法也有很多 这里我来讲一个我以前用的一个方法 正常的跳跃 如果使用物理引擎的话 就直接给一个向上的力就可以了 但是有一些游戏 例如跑酷 角色的移动速度都是越来越快的 而如果还是只给一个向上的
  • 【第2篇】VGG——引用最多的论文

    文章目录 摘要 1 引言 2 ConvNet配置 2 1 架构 2 2 配置 2 3 讨论 3 分类框架 3 1 训练 3 2 测试 3 3 实现细节
  • 什么是TPS,什么是QPS,区别是什么?

    一 TPS Transactions Per Second 每秒传输的事物处理个数 即服务器每秒处理的事务数 TPS包括一条消息入和一条消息出 加上一次用户数据库访问 业务TPS CAPS 每个呼叫平均TPS TPS是软件测试结果的测量单位
  • SpringBoot项目jwt生成token集成redis

    业务逻辑 1 用户登录 使用jwt生成token 2 后端把这个token返回给前端 同时把这个token作为key存储在redis中 用户对象作为value 并设置一个过期时间 3 用户以后每次访问都携带这个token 如果这个token