Redis实战-session共享之修改登录拦截器
在上一篇中Redis实战之session共享,我们知道了通过Redis实现session共享了,那么token怎么续命呢?怎么刷新用户呢?本来咱们就通过拦截器来实现这两个功能。
登录拦截器优化:
凯哥自己开发的,领取外卖、打车、咖啡、买菜、各大电商的优惠券的公¥众¥号。如下图:
正文开始
先来看看现在拦截器情况:
拦截流程:
当拦截器拦截需要拦截到的url时候,才会在拦截器中更新用户token的过期时间。那如果,访问了不被拦截的路径,就不会给token续命的。这样就会导致用户token过期,而重新登录的。这样是不对的。
拦截了哪些路径?在config/MvcConfig中
当访问以上这些路径的是,就不会自动更新用户的token过期时间了。
优化:我们可以在现有拦截器签名价格拦截器:
将获取用户,存放threadLocal及刷新token放到新的拦截器中。
第一个拦截器就叫做:刷新token拦截器;第二个拦截器就叫做:用户拦截器
创建刷新token的拦截器:
1 | import cn.hutool.core.bean.BeanUtil;<br> import com.hmdp.dto.UserDTO;<br> import com.hmdp.utils.UserHolder;<br> import org.springframework.data.redis.core.StringRedisTemplate;<br> import org.springframework.util.StringUtils;<br> import org.springframework.web.servlet.HandlerInterceptor;<br> <br> import javax.servlet.http.HttpServletRequest;<br> import javax.servlet.http.HttpServletResponse;<br> import java.util.Map;<br> import java.util.concurrent.TimeUnit;<br> <br> import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_KEY;<br> import static com.hmdp.constants.RedisConstants.LOGIN_USER_TOKEN_TTL;<br> <br> /**<br> * @author 凯哥Java<br> * @description 刷新用户token的烂机器<br> * @company<br> */ <br> public class RefreshTokenInterceptor implements HandlerInterceptor {<br> <br> private StringRedisTemplate stringRedisTemplate;<br> <br> /**<br> * 因为这个类不能被spring管理,所以不能直接注入RedisTemplate对象。通过构造函数传递<br> *<br> * @param stringRedisTemplate<br> */ <br> public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {<br> this .stringRedisTemplate = stringRedisTemplate;<br> }<br> <br> @Override<br> public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {<br> //1:从请求中获取到token<br> String token = request.getHeader("authorization");<br> if (StringUtils.isEmpty(token)) {<br> return true;<br> }<br> //2:基于token获取redis中用户对象<br> String key = LOGIN_USER_TOKEN_KEY + token;<br> Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);<br> //3:判断<br> if (userMap.isEmpty()) {<br> return true;<br> }<br> //将map转对象<br> UserDTO user = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);<br> UserHolder.saveUser(user);<br> //刷新token的过期时间<br> stringRedisTemplate.expire(key, LOGIN_USER_TOKEN_TTL, TimeUnit.MINUTES);<br> return true;<br> }<br> <br> <br> @Override<br> public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {<br> UserHolder.removeUser();<br> }<br>} |
修改用户拦截器:
1 | import com.hmdp.utils.UserHolder;<br> import org.springframework.web.servlet.HandlerInterceptor;<br> <br> import javax.servlet.http.HttpServletRequest;<br> import javax.servlet.http.HttpServletResponse;<br> <br> /**<br> * @author 凯哥Java<br> * @description 登录拦击器<br> * @company<br> */ <br> public class UserInterceptor implements HandlerInterceptor {<br> <br> <br> @Override<br> public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {<br> //判断是否需要拦截<br> if (UserHolder.getUser() == null) {<br> response.setStatus(401);<br> return false;<br> <br> }<br> return true;<br> }<br> <br> <br> @Override<br> public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {<br> UserHolder.removeUser();<br> }<br>} |
修改MvcCofig。将两个拦截器添加进去,并设置拦截顺序:
1 | import com.hmdp.interceptor.RefreshTokenInterceptor;<br> import com.hmdp.interceptor.UserInterceptor;<br> import org.springframework.context.annotation.Configuration;<br> import org.springframework.data.redis.core.StringRedisTemplate;<br> import org.springframework.web.servlet.config.annotation.InterceptorRegistry;<br> import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;<br> <br> import javax.annotation.Resource;<br> <br> /**<br> * @author 凯哥Java<br> * @description mvn的配置-添加拦截器<br> * @company<br> */ <br>@Configuration<br> public class MvcConfig implements WebMvcConfigurer {<br> <br> @Resource<br> private StringRedisTemplate stringRedisTemplate;<br> @Override<br> public void addInterceptors(InterceptorRegistry registry) {<br> //登录拦截器<br> registry.addInterceptor(new UserInterceptor())<br> .excludePathPatterns(<br> "/shop/**",<br> "/voucher/**",<br> "/shop-type/**",<br> "/upload/**",<br> "/blog/hot",<br> "/user/code",<br> "/user/login"<br> ).order(1);<br> //刷新token拦截器<br> registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);<br> }<br>} |
本文来自博客园,作者:kaizi1992,转载请注明原文链接:https://www.cnblogs.com/kaigejava/p/17111802.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体