問題使用攔截器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;
}
```