因爲項目後端是重寫了WebMvcConfigurer,然後添加的跨域請求。添加攔截器之後,根據token信息返回狀態響應碼並且preHandle返回的是false。熟悉攔截器的可知,preHandle返回false後會終止請求,也就是說後面配置的跨域方法不起作用了,這也就造成了前端的跨域問題。所以需要在攔截器中配置跨域請求才能解決。
代碼如下:
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//從http請求頭中取出token
String token = request.getHeader("Authorization");
//如果不是方法級別的請求,則直接通過
if (!(handler instanceof HandlerMethod)){
return true;
}
//利用java反射獲取到請求的方法
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
//如果方法添加了LoginToken註解
if(method.isAnnotationPresent(LoginToken.class)){
LoginToken loginToken = method.getAnnotation(LoginToken.class);
if (loginToken.required()){
//解決跨域問題
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.addHeader("Access-Control-Max-Age", "3600");
//未登錄
if(token == null){
response.setStatus(401);
return false;
}
String uid = "";
try {
uid = JWT.decode(token).getAudience().get(0);
}catch (JWTDecodeException jd){
//token取數據出問題
response.setStatus(401);
return false;
}
//獲取用戶信息
Users users = userService.findById(Integer.parseInt(uid));
if (users == null){
//用戶不存在
response.setStatus(401);
return false;
}
String token1 = (String)valueOperations.get(token.split("\\.")[2]);
//token過期(登錄過期)
if (token1 == null){
response.setStatus(403);
return false;
}
//token錯誤(未登錄)
if (!StringUtils.equals(token1,token)){
response.setStatus(401);
return false;
}
}
return true;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}