【Java】自定义登陆拦截器

开发场景:正在开发的这个项目后台登陆系统用的授权是oauth2.0机制,token有效期是8个小时,客户提了一个需求:使当前系统登陆之后半小时内没有操作就需要重新登陆,所以我这里决定用Redis缓存+拦截器来实现,前端每次请求除登陆之外的接口都需要走拦截器,首先我们登陆的时候会把用户id存入redis中,有效时间30分钟,其次访问其他接口的时候走拦截器,查询Redis中是否存在登陆信息,如果存在就重新插入redis,有效时间30分钟覆盖之前的redis数据,如果不存在说明超过30分中未进行其他操作,抛出异常提示客户端登陆超时重新登陆,自定义拦截器代码如下:

package com.gmac.backend.management.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.gmac.backend.management.controller.BaseController;
import com.gmac.backend.management.redis.RedisService;
import com.gmac.common.utils.StringUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 自定义登录拦截器
 * @author V_PS68C7
 *
 */
@Slf4j
@Component
public class LoginInterceptor extends BaseController implements HandlerInterceptor {
    
    @Autowired
    private RedisService redisService;
    
    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object)  {
        log.debug("[START] - check userId");
        String userId = super.getUserId();
        //从Redis中读取userId
        if(StringUtil.isNullOrEmpty(userId)) {
            log.debug("[error] - userId is empty");
            throw new InvalidTokenException("userId为空");
        } else {
            //验证userId在Redis中是否存在
            boolean check = redisService.checkUserId(userId);
            if(check) {
                //存在就重新添加覆盖掉之前的
                redisService.addUserId(userId);
                log.debug("[DEBUG] - 重新添加用户id到Redis");
            } else {
                //不存在就抛出异常
                String errorMsg = "用户访问超时 用户ID : ".concat(userId);
                log.debug("[error] - Landing timeout return:{}", errorMsg);
                throw new InvalidTokenException(errorMsg);
            }
        }
        log.debug("[END] - check userId");
        return true;
    }

    /**
     * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object, Exception e) throws Exception {

    }
}
package com.gmac.backend.management.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;

import com.gmac.common.constant.PermitAllUrl;

/**
 * 加载拦截器
 * @author V_PS68C7
 *
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Autowired
    private LoginInterceptor loginInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(PermitAllUrl.permitAllUrl("/users-anon/**","/login/**","/catalog/**"));
    }
}
原文地址:https://www.cnblogs.com/qinxiaowan/p/10844289.html