springboot(八)攔截器之驗證登入
阿新 • • 發佈:2019-01-02
新增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 {
}