由于HTTP协议的无状态性,我们可以用过cookie和session来标识某个用户,session实际上也是利用cookie来实现的,一般在请求头中看到的JSESSION=一串字符就是,如果客户端禁用了cookie,我们可以用通过url重写的方式来替代cookie
我们再来看一下request.getSession方法的解释
HttpSession getSession(boolean create)
Returns the current HttpSession associated with this request or, if there is no current session and create is true, returns a new session. If create is false and the request has no valid HttpSession, this method returns null.就是说你不可能在一个方法里创建一个新的session来把前面已存在的session覆盖掉,否则session岂不是乱了
一般某个用户登录后,我们会把他的信息存在session里,如:
session.setAttribute("user", true);
而session是由web容器,如tomcat来维护的,容器会为session生成一个唯一ID,该ID可以通过session.getId()方法获得,然后,服务器会把该ID返回给浏览器,类似
Set-Cookie:JSESSIONID=C7328DFC03B54841EA5A11127791CEF5; Path=/SpringSecurityStudy/; HttpOnly这样,用户访问其他页面时会带上信息,如:
Cookie:JSESSIONID=C7328DFC03B54841EA5A11127791CEF5这时在服务端,我们就可以通过session.getAttribute("user") == true来判断用户是否登录,而实际上web容器会根据你的JSESSIONID找到对应的session,然后再取得该session的"user"值
session在服务端是有生命周期的,tomcat的话默认是30分钟,当然我们可以进行配置,或者在程序中设置,session在浏览器端是通过内存形式的cookie来存储的,也就是说如果浏览器关闭,该cookie也就消失了,但是在服务端的session不会立即消失,只到超时才会消失
我们可以通过发送请求来通知服务端来使session失效,这便是注销
在SpringSecurity中,我们一般通过
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
来获取当前登录用户
实际上是,用户登录后,会执行以下操作session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContext);
SecurityContextHolder.getContext() == session.getAttribute("SPRING_SECURITY_CONTEXT")所以我们也可以通过
((SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT")).getAuthentication().getPrincipal();来取得用户
所以综上,SpringSecurity也是通过session来判断用户是否登录
值得一提的是,当我们访问JSP页面时,发现始终会有JSESSIONID,通过查看JSP页面生成的servlet会使用
session = pageContext.getSession();
所以一定会有session,这也说明了为什么在JSP页面中可以使用内置对象session