【SpringBoot拦截器】

SpringBoot拦截器的使用

作用:每次调接口先进拦截器(如果哪些请求地址不需要拦截可以配置里加入到白名单),主要用在平台登录

具体使用:

  1. 创建我们自己的拦截器类并实现 HandlerInterceptor 接口
/**
 1. 拦截器,每次调接口先进拦截器
 2.  3. @author 苏育科 
 4. @date 2020/06/08 16:49
 */
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest,
                             HttpServletResponse httpServletResponse,
                             Object object) {
        //之里面主要写自己的拦截逻辑

        //1.请求方式为OPTIONS直接跳过返回true
        String method = httpServletRequest.getMethod();
        if (method.equals(HttpMethod.OPTIONS.toString())) {
            return true;
        }

        //2.获取IP,打印日志 TODO 后续优化为统一工具类
        String ip = IpUtils.getIpAddress(httpServletRequest);

        //3.从请求头获取Token
        String token = httpServletRequest.getHeader("token");

        //4.Token为空直接返回false
        if (StringUtils.isBlank(token)) {
            log.error("[拦截器] token为空,请求失败 ip=[{}]", ip);
            addMessageToResponse(httpServletResponse, HttpStatus.UNAUTHORIZED);
            return false;
        }

        //5.从Redis获取登陆用户信息
        String userInfoKey = RedisKeyUtils.getUserInfoKey(token);
        SystemUserVo systemUserVo = (SystemUserVo) redisUtils.get(userInfoKey);

        //6.用户信息为空,代表登陆TOKEN已过期
        if (null == systemUserVo) {
            addMessageToResponse(httpServletResponse, HttpStatus.UNAUTHORIZED);
            log.error("[拦截器] 用户信息过期,请重新登录 ip=[{}] token=[{}]", ip, token);
            return false;
        }

        //7.重置Redis用户信息的过期时间
        redisUtils.expire(userInfoKey, RedisConstants.SYSTEM_USERINFO.getExpireTime());

        //8.设置Redis用户对应TOKEN的过期时间
        String userTokenKey = RedisKeyUtils.getUserTokenKey(systemUserVo.getLoginName());
        redisUtils.expire(userTokenKey, RedisConstants.SYSTEM_USERTOKEN.getExpireTime());

        //8.把用户名和token存入Request,方便后面的使用
        httpServletRequest.setAttribute("loginName", systemUserVo.getLoginName());
        httpServletRequest.setAttribute("userName", systemUserVo.getName());
        httpServletRequest.setAttribute("token", token);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) {
    }

    /**
     * 将异常信息写入响应体
     *
     * @param response   HTTP响应
     * @param httpStatus HTTP响应状态
     * @throws IOException IO异常
     */
    private void addMessageToResponse(HttpServletResponse response, HttpStatus httpStatus) {

        //1.设置响应异常状态
        response.setStatus(httpStatus.value());
        response.setContentType("application/json;charset=UTF-8");

        //2.响应异常信息写入
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.write(httpStatus.getReasonPhrase().getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 创建一个Java类继承WebMvcConfigurer,并重写 addInterceptors 方法。 实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。
/**
 1. @author 苏育科 
 2. @date 2020/06/08 16:48
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private WhiteListConfig whiteListConfig;

    @Bean
    AuthInterceptor authlInterceptor() {
        return new AuthInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //获取白名单
        List<String> whiteListUrl = whiteListConfig.getUrl();

        registry.addInterceptor(authlInterceptor())
                .addPathPatterns("/**")
                //白名单里的url可以不通过拦截器
                .excludePathPatterns(whiteListUrl);
    }
}
  1. 白名单
/**
 1. @author 苏育科 
 2. @date 2020-11-19 10:43:31
 3. @describe:
 */
@Component
@ConfigurationProperties(prefix = "yuffie2.white-list")
@Data
public class WhiteListConfig {

    /**
     * 白名单的URL从配置文件里获取
     */
    private List<String> url;
}
  1. 配置白名单
# 自定义配置
yuffie2:
  # 白名单配置
  white-list:
    url:
      - /swagger-resources/**
      - /webjars/**
      - /v2/**
      - /swagger-ui.html/**
      - /api/v1/tokens
SpringBoot拦截器是一种用于拦截和处理请求的组件。在SpringBoot中,我们可以通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`类来创建自定义的拦截器拦截器可以在请求被处理之前和之后执行一些操作,比如验证用户身份、记录日志等。 在SpringBoot中,拦截器的配置可以通过实现`WebMvcConfigurer`接口来完成。我们可以在`addInterceptors`方法中添加我们自定义的拦截器,并指定拦截的路径。例如,我们可以使用`registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")`来添加一个拦截器,并拦截所有的请求。 拦截器与过滤器的区别在于归属和内容。过滤器属于Servlet技术,而拦截器属于SpringMVC技术。过滤器对所有访问进行增强,而拦截器仅针对SpringMVC的访问进行增强。在SpringBoot中,我们可以通过配置类来添加拦截器,如`WebConfig`和`AdminWebConfig`。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [Springboot——拦截器](https://blog.csdn.net/weixin_51351637/article/details/128058053)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Springboot实现拦截器功能](https://blog.csdn.net/weixin_52875557/article/details/123793361)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值