在上一篇中Redis实战之session共享,我们知道了通过Redis实现session共享了,那么token怎么续命呢?怎么刷新用户呢?本来咱们就通过拦截器来实现这两个功能。

登录拦截器优化:

凯哥自己开发的,领取外卖、打车、咖啡、买菜、各大电商的优惠券的公¥众¥号。如下图:

正文开始

先来看看现在拦截器情况:

拦截流程:

当拦截器拦截需要拦截到的url时候,才会在拦截器中更新用户token的过期时间。那如果,访问了不被拦截的路径,就不会给token续命的。这样就会导致用户token过期,而重新登录的。这样是不对的。

拦截了哪些路径?在config/MvcConfig中

当访问以上这些路径的是,就不会自动更新用户的token过期时间了。

优化:我们可以在现有拦截器签名价格拦截器:

将获取用户,存放threadLocal及刷新token放到新的拦截器中。

第一个拦截器就叫做:刷新token拦截器;第二个拦截器就叫做:用户拦截器

创建刷新token的拦截器:

import cn.hutool.core.bean.BeanUtil;
import com.hmdp.dto.UserDTO;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;
 
import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_KEY;
import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_TTL;
 
/**
 * @author 凯哥Java
 * @description 刷新用户token的烂机器
 * @company
 */
public class RefreshTokenInterceptor implements HandlerInterceptor {
 
    private StringRedisTemplate stringRedisTemplate;
 
    /**
     * 因为这个类不能被spring管理,所以不能直接注入RedisTemplate对象。通过构造函数传递
     *
     * @param stringRedisTemplate
     */
    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1:从请求中获取到token
        String token = request.getHeader("authorization");
        if (StringUtils.isEmpty(token)) {
            return true;
        }
        //2:基于token获取redis中用户对象
        String key = LOGIN_USER_TOKEN_KEY + token;
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);
        //3:判断
        if (userMap.isEmpty()) {
            return true;
        }
        //将map转对象
        UserDTO user = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        UserHolder.saveUser(user);
        //刷新token的过期时间
        stringRedisTemplate.expire(key, LOGIN_USER_TOKEN_TTL, TimeUnit.MINUTES);
        return true;
    }
 
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.removeUser();
    }
}

修改用户拦截器:

import com.hmdp.utils.UserHolder;
import org.springframework.web.servlet.HandlerInterceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * @author 凯哥Java
 * @description 登录拦击器
 * @company
 */
public class UserInterceptor implements HandlerInterceptor {
 
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断是否需要拦截
        if (UserHolder.getUser() == null) {
            response.setStatus(401);
            return false;
 
        }
        return true;
    }
 
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.removeUser();
    }
}

修改MvcCofig。将两个拦截器添加进去,并设置拦截顺序:

import com.hmdp.interceptor.RefreshTokenInterceptor;
import com.hmdp.interceptor.UserInterceptor;
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;
 
import javax.annotation.Resource;
 
/**
 * @author 凯哥Java
 * @description  mvn的配置-添加拦截器
 * @company
 */
@Configuration
public class MvcConfig implements WebMvcConfigurer {
 
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //登录拦截器
        registry.addInterceptor(new UserInterceptor())
                .excludePathPatterns(
                        "/shop/**",
                        "/voucher/**",
                        "/shop-type/**",
                        "/upload/**",
                        "/blog/hot",
                        "/user/code",
                        "/user/login"
                ).order(1);
        //刷新token拦截器
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);
    }
}

Redis实战-session共享之修改登录拦截器的更多相关文章

  1. 基于SpringBoot+Redis的Session共享与单点登录

    title: 基于SpringBoot+Redis的Session共享与单点登录 date: 2019-07-23 02:55:52 categories: 架构 author: mrzhou tag ...

  2. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-10.Springboot2.x用户登录拦截器开发实战

    笔记 10.Springboot2.x用户登录拦截器开发实战     简介:实战开发用户登录拦截器拦截器 LoginInterceptor                  1.实现接口 LoginI ...

  3. 单点登录实现(spring session+redis完成session共享)

    一.前言 项目中用到的SSO,使用开源框架cas做的.简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩. 二.工程结构 我模拟了 sso的客户端和s ...

  4. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  5. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

    因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...

  6. Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享

    小伙伴们好久不见!最近略忙,博客写的有点少,嗯,要加把劲.OK,今天给大家带来一个JavaWeb中常用的架构搭建,即Nginx+Tomcat搭建服务集群,然后通过Spring Session+Redi ...

  7. nginx+tomcat实现集群,redis实现session共享,软连接实现文件共享:http://blog.csdn.net/hua1586981/article/details/78132710

    转载 2017年02月08日 16:52:41 730 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能 ...

  8. [转]分布式中使用Redis实现Session共享(二)

    本文转自:http://www.cnblogs.com/yanweidie/p/4678095.html 上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见 ...

  9. (转)分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  10. 分布式Session共享(一):tomcat+redis实现session共享

    一.前言 本文主要测试redis实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port Tomcat ...

随机推荐

  1. 基于 .net core 8.0 的 swagger 文档优化分享-根据命名空间分组显示

    前言 公司项目是是微服务项目,网关是手撸的一个.net core webapi 项目,使用 refit 封装了 20+ 服务 SDK,在网关中进行统一调用和聚合等处理,以及给前端提供 swagger ...

  2. Python数据分析代码示例

    数据清洗 在进行数据分析之前,通常需要对原始数据进行清洗,即处理缺失值.异常值.重复值等问题. 下面是一个数据清洗的示例代码: import pandas as pd # 读取原始数据 data = ...

  3. yb课堂 注册-登陆-个人模块 《三十九》

    Cube-UI的form表单 https://didi.github.io/cube-ui/#/zh-CN/docs/form 注册 Register.vue <template> < ...

  4. 洛谷P1043

    [NOIP2003 普及组] 数字游戏 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前 ...

  5. IDEA之调试或运行的小助手日志插件Grep Console:不同颜色区分,查看日志看方便【工欲善其事必先利其器】

    简介 Grep Console是一款方便开发者对idea控制台输出日志进行个性化管理的插件.这个插件还是很用的,在满屏的日志中,迅速找到自己关注的内容,调试程序的绝佳工具. 功能特性 Grep Con ...

  6. AT_arc113_c 题解

    洛谷链接&Atcoder 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 现在有一个字符串 \(S\),每一次你可以选择一个 \(i(1 \le i \le | ...

  7. 工作单元(UnitOfWork) 模式 (1)

    在开始UnitOfWork模式之前有必要回顾下我们耳熟能详的Data Access Object(DAO)模式,即数据访问对象.DAO是一种简单的模式,我们构建应用的时候经常会使用到它,它的功能就是将 ...

  8. Gradle配置文件解析和使用Meven本地仓库

    Gradle配置文件 使用Gradle创建好项目之后,项目的根目录下会有一个build.gradle文件,该文件就是Gradle的核心配置文件 对应的信息: plugins { id 'java' } ...

  9. 【OracleDB】 10 数据处理 DML

    DML(Data Manipulation Language – 数据操纵语言) - 向表中插入数据 - 修改现存数据 - 删除现存数据 [事务是由完成若干项工作的DML语句组成的] INSERT 语 ...

  10. 【Layui】13 轮播 Carousel

    文档地址: https://www.layui.com/demo/carousel.html 基础轮播: <style> /* 为了区分效果 */ div[carousel-item]&g ...