`

Redis实战-session共享之修改登录拦截器

 
阅读更多

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

登录拦截器优化:

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

6e649d0b148042138a07e16e7677f4df.png

拦截流程:

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

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

303aefeaefa995213ab88207d6a21c37.png

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

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

915557733da7a2752022aeb98d4dddd0.png

将获取用户,存放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);
    }
}

 

 

 

 

分享到:
评论

相关推荐

    SSM REDIS集成实战

    此外,你还可以使用Redis存储Session,提高多服务器环境下的Session共享能力。配置`sessionManager`和`httpSessionStrategy`,将Session存储到Redis中: ```xml &lt;bean id="sessionManager" class="org.spring...

    spring session实现session共享

    4. **Filter**: 为了实现Session共享,Spring Session 使用一个自定义的Servlet过滤器(`DelegatingSessionFilter`),这个过滤器负责拦截HTTP请求,处理Session相关操作。 5. **Spring Boot集成**: 如果使用Spring...

    ssm框架+shiro+redis缓存(某课网代码)

    将用户的session信息存储在Redis中,解决单机环境下session共享问题,提升多服务器环境下的用户体验。 3. **Spring配置**:Spring配置文件会定义Bean的依赖注入,包括SSM框架的各个组件,如DataSource、...

    .NET Core 跨平台实战(含源码).pdf

    - **Session 管理**:在 .NET Core 中,可以通过配置支持多种类型的分布式 Session,比如 Redis、SQL Server 等。 - **实现过程**:首先需要在 `Startup.cs` 中配置对应的 Session 存储服务,然后在需要使用的地方...

    基于springboot整合shiro完整代码案例demo

    - **拦截器**:配置Shiro的拦截器,对特定的URL进行访问控制,未登录用户访问受保护资源时会被重定向到登录页面。 - **权限控制**:根据角色和权限分配,实现不同级别的访问控制,如用户只能查看自己的信息,管理...

    Guns技术文档.docx

    - **多机器部署开启SpringSession**:指导用户如何在多台服务器之间共享会话状态。 - **使用Redis**:介绍如何集成Redis作为Guns项目的缓存和会话存储方案。 - **XSS过滤器**: - **介绍**:解释XSS攻击的概念及其...

    Guns 技术文档 v5.1.pdf

    - **多机器部署开启SpringSession**:说明了在集群环境中如何启用SpringSession来实现会话共享。 - **使用Redis**:讲解了Redis在Guns中的集成方法及其应用场景。 - **XSS过滤器**: - **介绍**:简述了XSS攻击的...

    springboot-shiro.zip

    Shiro支持Session管理,可以实现会话超时、跨域Session共享等功能。对于博客系统,可以设置会话过期后自动登出。 4. **安全策略** 设置Shiro的安全策略,如未登录用户访问受保护页面时重定向至登录页,或者匿名...

    shiro学习笔记.rar

    可以根据需求自定义过滤器,例如实现登录拦截、权限校验等。在`shiro.ini`配置文件或Java配置中定义过滤器链,指定过滤器的执行顺序和处理逻辑。 **7. 安全会话管理** Shiro提供了会话管理功能,可以控制会话超时、...

Global site tag (gtag.js) - Google Analytics