springboot+vue前后端分离项目,拦截器获取不到session的问题,和解决思路
前后端分离的项目,浏览器发送请求给服务器通常都要发送两次,其中一次是options类型的请求,可打开network查看,主要是为了验证服务器是否可用,而options请求又不会携带我们自定义的header数据,所以必然会被拦截器给拦截,导致二次请求失败,因此对于options类型的请求必须无条件放行if (request.getMethod().equals("OPTIONS")) {return
前后端分离的项目,浏览器发送请求给服务器通常都要发送两次,
其中一次是options类型的请求,可打开network查看,主要是为了验证服务器是否可用,而options请求又不会携带我们自定义的header数据,所以必然会被拦截器给拦截,导致二次请求失败,因此对于options类型的请求必须无条件放行
if (request.getMethod().equals("OPTIONS")) {
return true;
}
现在options请求可以通过,但是无法获取session里面的数据,而在登录成功时明明把用户数据放进了session里,可取出来时为null,这是因为前后端分离的项目每次请求的sessionid都不同,所以取不出来数据,原因如下:
在前后端分离的项目中,浏览器第一次访问服务器时,在响应头中会包含set-cookie,里面放置着JSESSIONID,浏览器则会将JSESSIONID设置到Cookies中保存。当浏览器再次发送请求到服务器时,会在请求头中携带cookie信息,其内容即为JSESSIONID。当用户访问服务器的时候会为每一个用户开启一个session,JSESSIONID就是被用来判断当前用户对应于哪个session的。
解决sessionid不一致的问题方法
axios.defaults.withCredentials = true
现在options请求验证的问题解决了,sessionid不同的问题也解决了,但还是不行,那是因为跨域的问题,可我已经在controller中配置了@CrossOrigin注解,最后发现在controller中配置跨域并不能解决拦截器的跨域问题,所以最后增加了统一配置
package com.oa.config;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class Myconfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login","/user/logout");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders(CorsConfiguration.ALL)
.allowedMethods(CorsConfiguration.ALL)
.allowCredentials(true)
.maxAge(3600); // 1小时内不需要再预检(发OPTIONS请求)
}
}
这样所有的问题就解决了,一共3步。完整代码如下
拦截器类
package com.oa.config;
import com.oa.enums.CommonEnum;
import com.oa.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Slf4j
public class MyInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals("OPTIONS")) {
return true;
}
String token = request.getHeader("token");
if (StringUtils.isEmpty(token)){
throw new CommonException(CommonEnum.USER_NOT_LOGIN);
}
Object user = request.getSession().getAttribute(token);
log.info("拦截器token={},user={}",token,user);
if (user == null) {
throw new CommonException(CommonEnum.USER_NOT_LOGIN);
}else {
return true;
}
}
}
配置类
package com.oa.config;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class Myconfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login","/user/logout");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders(CorsConfiguration.ALL)
.allowedMethods(CorsConfiguration.ALL)
.allowCredentials(true)
.maxAge(3600); // 1小时内不需要再预检(发OPTIONS请求)
}
}
更多推荐
所有评论(0)