(一)问题背景
因为拦截器是在上下文容器 Spring Context 初始化之前执行,所以没有办法直接在拦截器中注入Service对象,解决办法如下:
(二)拦截器中注入Bean对象
package com.yuedu.config;
import com.yuedu.interceptor.SessionInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 咸鱼
* @date 2019-03-11 22:45
*/
@Configuration
public class WebAppConfigure implements WebMvcConfigurer {
@Bean
public SessionInterceptor sessionInterceptor(){
return new SessionInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sessionInterceptor());
}
}
package com.yuedu.interceptor;
import com.yuedu.entity.ResultEnum;
import com.yuedu.entity.User;
import com.yuedu.exception.BaseException;
import com.yuedu.service.UserService;
import com.yuedu.util.FinalName;
import com.yuedu.util.Md5Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 咸鱼
* @date 2019-03-11 21:37
*/
public class SessionInterceptor extends HandlerInterceptorAdapter {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
if (request.getSession().getAttribute(FinalName.SESSION_USER) != null) {
return true;
}
String token = request.getHeader("token");
/*
* 若token为空,有以下几个可能:
* 一、第一次使用,未登录过,此时请求调用的应该是“/user/login”,该请求通过,这里不再处理
* 二、以前登陆过,但是缓存被删除了,此时请求调用的应该是“/user/login”,该请求通过,这里不再处理
* 二、并未带token参数,说明该请求无需身份验证,这里不再处理
* 所以,这里的业务逻辑是:
* 若带了token,就进行验证,验证通过,则存入Session,没带,则不处理。(PS:若某些页面需要登录才能访问,
* 则由后续逻辑判断Session中是否有User,有则表明已登录,无则无法处理后续逻辑)
*/
return StringUtils.isBlank(token) || validateLoginWithToken(token, request);
} else {
return super.preHandle(request, response, handler);
}
}
/**
* 验证身份,并存入session
* @param token 验证标识
* @param request 请求对象
* @return true:验证通过 false:验证失败
*/
private boolean validateLoginWithToken(String token, HttpServletRequest request) {
String encryptOpenId = token.split(":")[0];
Long userId = Long.valueOf(token.split(":")[1]);
User user = new User();
user.setId(userId);
User userInDb = userService.selectUser(user);
if (userInDb == null) {
throw new BaseException(ResultEnum.USER_NOT_EXISTS);
}
if (encryptOpenId.equals(Md5Utils.getMd5WithSalt(userInDb.getOpenId(), FinalName.MD5_SALT))){
request.getSession().setAttribute(FinalName.SESSION_USER, userInDb);
return true;
} else {
throw new BaseException(ResultEnum.TOKEN_IS_ERROR);
}
}
}