1.vue前端
// response 拦截器
service.interceptors.response.use(
response => {
//省略=======================
},
error => {
switch(error.response && error.response.status){
case 401:
//身份验证错误
//弹出之前就清空,以免不点确定就刷新
store.dispatch("app/setCurrentUser", "");
store.dispatch("app/setToken", "");
store.dispatch("app/setSSOUser", "");
Vue.prototype.$xpAlert("您好,token已经失效,请重新登陆!","warning",function(){
router.push('./login');
});
break;
}
return Promise.reject(error);
}
)
2.后端
2.1拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 跨域拦截器,用于401处理
* @author Xiangzhong Wang
* @date 2019-12-12 10:44:34
*/
@Configuration
public class CrossInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String origin = request.getHeader(HttpHeaders.ORIGIN);
if (origin != null) {
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Access-Token");
response.setHeader("Access-Control-Max-Age", "3600");
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
2.2注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* 注册跨域拦截器,用于401处理
* @author Xiangzhong Wang
* @date 2019-12-12 10:44:34
*/
@Configuration
class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CrossInterceptor()).addPathPatterns("/**");
System.out.println("跨域拦截器注册成功!");
}
}
2.3错误处理
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 认证异常处理
* @author Xiangzhong Wang
* @date 2019-11-29 10:44:34
*/
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException)
throws ServletException {
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, it-req-wrap");
response.setHeader("Access-Control-Allow-Methods","*");
response.setHeader("Access-Control-Allow-Origin", "*");
Map map = new HashMap();
map.put("error", "401");
map.put("message", authException.getMessage());
map.put("path", request.getServletPath());
map.put("timestamp", String.valueOf(new Date().getTime()));
response.setContentType("application/json");
//1.vue会发生跨域捕捉不到error
//response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//2.vue可以捕获到error
try {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"token已经失效");
} catch (IOException e) {
e.printStackTrace();
}
try {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getOutputStream(), map);
} catch (Exception e) {
throw new ServletException();
}
}
}