1. 程式人生 > >springboot(八)攔截器之驗證登入

springboot(八)攔截器之驗證登入

新增jar包,這個jar包不是必須的,只是在攔截器裡用到了,如果不用的話,完全可以不引入

<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.5</version>
		</dependency>

springboot預設為Tomcat,如果用jetty,還需要引入

<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>


1、以登入驗證為例,首先建立個@Auth註解

package com.demo.interceptor;

import java.lang.annotation.*;

/**
 * Created by huguoju on 2016/12/30.
 * 在類或方法上新增@Auth就驗證登入
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {
}
2、建立一個Constants,在攔截器裡用
package com.demo.util;

/**
 * Created by huguoju on 2016/12/30.
 */
public interface Constants {
    int MAX_FILE_UPLOAD_SIZE = 5242880;
    String MOBILE_NUMBER_SESSION_KEY = "sessionMobileNumber";
    String USER_CODE_SESSION_KEY = "userCode";
    String SESSION_KEY = "sessionId";
}

3、建立一個SessionData,用於儲存在session中的欄位
package com.demo.model;

import lombok.Data;

/**
 * Created by huguoju on 2016/12/30.
 */
@Data
public class SessionData {
    private Integer userCode;
    private String mobileNumber;
}


4、實現登入攔截實現

package com.demo.interceptor;

import com.demo.model.SessionData;
import com.demo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

import static com.demo.util.Constants.MOBILE_NUMBER_SESSION_KEY;
import static com.demo.util.Constants.SESSION_KEY;
import static com.demo.util.Constants.USER_CODE_SESSION_KEY;

/**
 * Created by huguoju on 2016/12/30.
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisUtil redisUtils;
    private final static String SESSION_KEY_PREFIX = "session:";
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        if (!handler.getClass().isAssignableFrom(HandlerMethod.class)) {
            return true;
        }
        handlerSession(request);

        final HandlerMethod handlerMethod = (HandlerMethod) handler;
        final Method method = handlerMethod.getMethod();
        final Class<?> clazz = method.getDeclaringClass();
        if (clazz.isAnnotationPresent(Auth.class) ||
                method.isAnnotationPresent(Auth.class)) {
            if(request.getAttribute(USER_CODE_SESSION_KEY) == null){
  
                 throw new Exception();
               
            }else{
                return true;
            }
        }

        return true;

    }
    public void  handlerSession(HttpServletRequest request) {
        String sessionId = request.getHeader(SESSION_KEY);
        if(org.apache.commons.lang3.StringUtils.isBlank(sessionId)){
            sessionId=(String) request.getSession().getAttribute(SESSION_KEY);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(sessionId)) {
            SessionData model = (SessionData) redisUtils.get(SESSION_KEY_PREFIX+sessionId);
            if (model == null) {
                return ;
            }
            request.setAttribute(SESSION_KEY,sessionId);
            Integer userCode = model.getUserCode();
            if (userCode != null) {
                request.setAttribute(USER_CODE_SESSION_KEY, Long.valueOf(userCode));
            }
            String mobile = model.getMobileNumber();
            if (mobile != null) {
                request.setAttribute(MOBILE_NUMBER_SESSION_KEY, mobile);
            }
        }
        return ;
    }
}

redisUtil在上一篇文章建立過了

5、配置攔截器

package com.demo.interceptor;

import org.hibernate.validator.HibernateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * Created by huguoju on 2016/12/30.
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.demo.controller")
@PropertySource(value = "classpath:application.properties",
        ignoreResourceNotFound = true,encoding = "UTF-8")
public class MvcConfig extends WebMvcConfigurerAdapter {
    private static final Logger logger = LoggerFactory.getLogger(MvcConfig.class);
    @Autowired
    LoginInterceptor loginInterceptor;

    /**

     * <p>
     *     檢視處理器
     * </p>
     *
     * @return
     */
    @Bean
    public ViewResolver viewResolver() {
        logger.info("ViewResolver");
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    /**
     * 攔截器配置
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 註冊監控攔截器
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
         .excludePathPatterns("/configuration/ui");

    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedHeaders("*/*")
                .allowedMethods("*")
                .maxAge(120);
    }

    /**
     * 資源處理器
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        logger.info("addResourceHandlers");
        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

以上就完成了,測試時可以在LoginInterceptor裡打斷點,然後在controller上或者方法上新增@Auth註解,

controller上新增以後這個controller裡所有請求都驗證登入,在方法裡新增只有請求這個方法時驗證

@Auth
@RestController
public class TestController {


}