①首先在登陆页面的时候,会发送验证码请求("http://127.0.0.1:10003/security/vcode?sysCode=102001"),在请求验证码后台接口里通过HttpServletRequest获取到前端传过来的信息。通过HttpSession session = request.getSession()
获得session,并将验证码信息存入到session里了,如下代码:
session.removeAttribute("vcode" + sysCode);
session.setAttribute("vcode" + sysCode, verifyCode.toLowerCase());
第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,我猜想request.getSession()方法内部新创建了Session之后一定是做了如下的处理:
//获取session的Id
String sessionId = session.getId();
//将session的Id存储到名字为JSESSIONID的cookie中
Cookie cookie = new Cookie("JSESSIONID", sessionId);
//设置cookie的有效路径
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
注:通过HttpServletRequest还可以获得前端请求头里的信息
Enumeration<String> headerNames = request.getHeaderNames();
Cookie[] cookies = request.getCookies();
String contentType = request.getContentType();
后台验证码接口:
/**
* 获取验证码接口
* @param request
* @param response
* @param sysCode 系统sysCode
* @throws Exception
*/
@RequestMapping(value = "/vcode", method = RequestMethod.GET)
public void getVCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String sysCode) throws
Exception {
try {
if (SecurityContextHolder.getContext().getAuthentication().isAuthenticated()
&& !(SecurityContextHolder.getContext().getAuthentication() instanceof
AnonymousAuthenticationToken))
request.logout();
} catch (Exception ex) {
}
HttpSession session = request.getSession();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
String verifyCode = VCodeUtil.generateVerifyCode(4);
log.debug(request.getRemoteAddr() + "获取验证码" + verifyCode);
Enumeration<String> headerNames = request.getHeaderNames();
Cookie[] cookies = request.getCookies();
String contentType = request.getContentType();
session.removeAttribute("vcode" + sysCode);
session.setAttribute("vcode" + sysCode, verifyCode.toLowerCase());
int w = 100, h = 30;
VCodeUtil.outputImage(w, h, response.getOutputStream(), verifyCode);
}
②springboot中关于共享session的配置见类HttpSessionConfig
因为项目使用了共享缓存,所以在登陆成功的时候,会将session通过redis存入内存,用RedisDesktopManager打开
③服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。
④因为session设置了缓存失效时间,所以当RedisDesktopManager打开后里的session失效了就意味着sessionId也失效了,前端发起请求的时候再用cookie来访问,但是cookie里的sessionId已经失效了,所以就会失败,目前做了一个处理就是如果缓存失效就直接跳转到登陆页。
当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。
HttpSession session = request.getSession();
//手工调用session.invalidate方法,摧毁session
session.invalidate();
链接:
Session和Cookie的主要区别
共享Session-spring-session-data-redis
【Spring】Redis的两个典型应用场景
网友评论