首页 > 其他 > 详细

拦截器

时间:2021-05-18 09:19:16      阅读:19      评论:0      收藏:0      [点我收藏+]

在开发中,我们在Controller或Service里,通常要根据token值获取到当前用户。这些代码是完全重复的,有什么方法可以解决掉这些重复代码吗?

我们这里通过拦截器和ThreadLocal结合,来解决这个问题

创建UserHolder

package com.tanhua.server.interceptor;

import com.tanhua.domain.db.User;

/**
 * @author liuyp
 * @date 2021/01/16
 */
public class UserHolder {
    private static ThreadLocal<User> tl = new ThreadLocal<>();

    /**
     * 把User对象绑定到当前线程
     * @param user user对象
     */
    public static void setUser(User user){
        tl.set(user);
    }

    /**
     * 从当前线程上获取绑定的User对象
     */
    public static User getUser(){
        return tl.get();
    }

    /**
     * 从当前线程上获取绑定的User对象的id
     */
    public static Long getUserId(){
        return tl.get().getId();
    }
}

  

创建拦截器

tanhua-servercom.tanhua.server.interceptor包里创建拦截器类:TokenInterceptor

package com.tanhua.server.interceptor;

import com.alibaba.fastjson.JSON;
import com.tanhua.domain.db.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;

/**
 * @author liuyp
 * @date 2021/01/25
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        if (token == null) {
            response.setStatus(401);
            return false;
        }

        User user = findByToken(token);
        if (user == null) {
            response.setStatus(401);
            return false;
        }

        UserHolder.setUser(user);
        return true;
    }

    private User findByToken(String token){
        //从redis中查找缓存的用户User
        String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
        if (userJson != null) {
            //找到用户后,给redis缓存的用户延长生存时间
            redisTemplate.opsForValue().set("TOKEN_" + token, userJson, Duration.ofHours(1));
            return JSON.parseObject(userJson, User.class);
        }
        return null;
    }
}

注册拦截器

注册拦截器;注册和登录放行,其他都拦截

package com.tanhua.server.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author liuyp
 * @date 2021/01/16
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        registry.addInterceptor(tokenInterceptor)
                //拦截范围:/**
                .addPathPatterns("/**")
                //不拦截范围:这两个请求路径,是登录前访问的,还没有生成token值,允许不允许token
                .excludePathPatterns("/user/login", "/user/loginVerification");
    }
}

 

拦截器

原文:https://www.cnblogs.com/zhangshy199/p/14779246.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!