问题使用拦截器session值无法获取到
需求:用户登录成功将登录信息存放在session中,拦截器根据获取session,判断是否session中的值过期,但是拦截器无法获取到session中的值
代码展示:
登录:
//登陆
@PostMapping("/login")
public ResponseResult userLogin (HttpServletRequest request,@RequestBody LoginPojo_ loginPojo_){
ResponseResult responseResult = new ResponseResult();
Admin admin = adminService.selectAdminId(loginPojo_.getUsername(),loginPojo_.getPassword());
if (ObjectUtils.isEmpty(admin) || admin == null) {
responseResult.setCode(100);
responseResult.setMessage("用户名密码错误");
//清空session
request.getSession().invalidate();
return responseResult;
} else if (loginPojo_.getValidateCode().equals("")){
responseResult.setCode(100);
responseResult.setMessage("请输入验证码");
//清空session
request.getSession().invalidate();
return responseResult;
} else{
responseResult.setCode(200);
responseResult.setMessage("登陆成功");
responseResult.setData(admin);
//保存到session中
request.getSession().setAttribute("username",admin.getUsername());
//设置session过期时间(单位秒)
request.getSession().setMaxInactiveInterval(120);
}
return responseResult;
}
配置拦截器:
@Component
public class CarInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
String sessionName = (String) session.getAttribute("username");
if(Objects.isNull(sessionName)){
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(200);
PrintWriter pw = response.getWriter();
//封装返回对象
ResponseResult responseResult = new ResponseResult();
responseResult.setCode(403);
responseResult.setData(Collections.emptyMap());
responseResult.setMessage("登录超时,请请重新登录");
pw.write(JSONObject.toJSONString(responseResult));
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
//登录超时
return false;
}
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 {
}
}
注册拦截器:
@Configuration
class CarWebInterceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//不拦截路径
List<String> urls = new ArrayList<>();
urls.add("/api/user/login");
urls.add("/api/select/carbrand");
urls.add("/api/user/shiro");
registry.addInterceptor(new CarInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(urls);
super.addInterceptors(registry);
}
}
问题:拦截器获取到的session一直为空
解决方法:
//在controller层添加以下注解,表示开启cookie
@CrossOrigin(allowCredentials = "true")
前端需要添加以下配置:
//在main.js中添加以下配置:
axios.defaults.withCredentials = true
但是这时候又会出现跨域问题:
解决方法:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
String sessionName = (String) session.getAttribute("username");
if(Objects.isNull(sessionName)){
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(200);
// response.setHeader("Cache-Control", "no-store");
// response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
PrintWriter pw = response.getWriter();
ResponseResult responseResult = new ResponseResult();
responseResult.setCode(403);
responseResult.setData(Collections.emptyMap());
responseResult.setMessage("登录超时,请请重新登录");
pw.write(JSONObject.toJSONString(responseResult));
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
//登录超时
return false;
}
return true;
}
```