session是因为cookie的弊端(存放在客户端,容易被客户修改伪造,数据量大也有纯传输问题) 才被做出来的,用session存储在服务器中,这让他的安全性也相对高一点。

Session的作用

session的作用是用于保存每个用户的专用信息,当用户访问时,服务器都会为每个用户分配唯一的Session ID,而且当访问其他程序时可以从用户的session中取出该用户的数据为用户服务。

Session的生命周期

session的数据保存在服务端内存中在客户端第一次访问服务器时创建,并分配一个唯一的Id,同时把id号发送到客户端,以JSESSIONID存入cookie,Session依据该cookie判断是否是同一客户端。

注意:只有访问动态网页才会创建session,访问静态网页是不会创建Session的。

在客户端不需要的时候销毁Session,使它不再占用服务器内存。服务器并不管客户端是否依然存在,因而它也无法确定客户端什么时间不再使用它,但是如果在客户端不再用的时候不及时销毁Session的话,服务器很快就会内存不足。为了解决这个问题,给Session加了一个生命周期,当服务器发现Session超过了它的生命周期,就会释放该Session所占用的内存空间。

Session的销毁

只有两种情况:
第一:session调用了session.invalidate()方法。
第二:前后两次请求超出了session指定的生命周期时间。

对第二种的解释:
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session”活跃(active)”了一次。当我们登陆一个网站,网站会记录我们的个人信息如用户名等,如果我们登陆了很长时间但是没有任何操作,那么session超时,我们再次操作时会让我们重新登陆。但是如果我们登陆后,一直在访问这个网站,就不会出现session超时的问题,我们也无需重新登陆。

分布式Session共享

假设第一次访问服务A生成一个sessionid并且存入cookie中,第二次却访问服务B客户端会在cookie中读取sessionid加入到请求头中,如果在服务B通过sessionid没有找到对应的数据那么它创建一个新的并且将sessionid返回给客户端,这样并不能共享我们的Session无法达到我们想要的目的。

解决方案

  • 使用cookie来完成(很明显这种不安全的操作并不可靠)
  • 使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(不支持负载均衡)
  • 利用数据库同步session(效率不高)
  • 使用tomcat内置的session同步(同步可能会产生延迟)
  • 使用token代替session
  • 我们使用spring-session以及集成好的解决方案,存放在redis中