在上一篇中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. 使用post请求登陆

    1.使用post请求登陆 import requests import matplotlib.pyplot as plt url = 'https://www.ptpress.com.cn/login ...

  2. Vue查询传参

    通过修改 getWK005 函数来实现这一点.这里的 query 参数就是发送 GET 请求时的查询参数.你可以将需要的条件作为 query 对象的属性传递进去.比如,如果你想要按照特定的条件查询信息 ...

  3. 关联的巧妙用法limit_choices_to

    sa_no = models.ForeignKey(CU004HModel, verbose_name='销货单', on_delete=models.PROTECT, related_name='C ...

  4. web259(超详细)

    SoapClient看完之后还不是很懂的话就可以去下面的两个网址去补充一下 SoapClient 是 PHP 中用于与 SOAP(Simple Object Access Protocol)服务进行通 ...

  5. CSP2023

    坐标HA 背景 NOIP都打完了,CSP-S都没写游记,所以来补一篇(逃-- 正文 Day 7*-1 考前一周停课集训,被whk老师怒斥不务正业,悲QWQ. Day 0 周五得到年级第一zyx的鼓励, ...

  6. 音频文件降噪及python示例

    操作系统 :Windows 10_x64 Python版本:3.9.2 noisereduce版本:3.0.2 从事音频相关工作,大概率会碰到降噪问题,今天整理下之前学习音频文件降噪的笔记,并提供Au ...

  7. JavaScript 常用 Web APIs

    Web APIs Web APIs DOM 页面文档对象模型 DOM 树 获取元素 事件 监听事件 事件解绑 操作元素 样式属性操作 结点操作 结点关系 创建节点 DOM 事件流 事件对象 常用鼠标事 ...

  8. 学习笔记--Java中this关键字

    Java中this关键字 关于Java语言中的this关键字 this 是一个关键字,翻译为:这个 this 是一个引用,一个变量,this变量中保存的内存地址指向自身 每一个对象都有自己的this, ...

  9. ABC350

    A link 把最后三位取成数字,判断是否小于\(349\),大于\(1\),不等于\(316\). 点击查看代码 #include<bits/stdc++.h> using namesp ...

  10. springboot3整合高版本spring data neo4j

    本博客适用于springboo data neo4j 7.2.6版本,详情阅读官网https://docs.spring.io/spring-data/neo4j/reference/7.2/intr ...