Session的理解
灵感来源于:https://www.cnblogs.com/lixinjie/p/a-yuanfen-between-session-and-me.html
在登陆时,request.getSession().setAttribute("userName", "lixinjie"),request.getSession().setAttribute("nickName", "李大胖")等。
在程序中如果要使用的话,是这样的request.getSession().getAttribute("nickName")等。
在登出时,是这样的request.getSession().removeAttribute("userName"),request.getSession().removeAttribute("nickName")等,终于知道用remove了。
来分析一下。在代码中是这样获取session的,request.getSession(),这个方法的意思是当有session时就返回session,当没有时就创建一个新的session再返回
1.Session是由tomcat(Servlet容器)创建的,驻留在内存里,每个Session都有一个唯一的Id标识,叫做session id。当用户登陆时,这个session id会被服务器写到cookie里传回客户端。(一个客户端请求代表创建一个session)
下次这个客户端再发起请求时就会把这个cookie带上,tomcat从cookie里解析出session id,然后去自己的所有session里找,如果找到session说明他已经登陆过了,反之则没有,要求他去登陆。
2.Servlet已经涵盖了JSP技术,因为JSP最终也会被编译为Servlet,两者有着相同的本质。
7.session设定的有效时间是-1,即无过期时间,完全用代码来控制session的过期。
这里有个问题,就是session的过期优先级是代码>web.xml配置>容器配置(我们容器用的tomcat),
但是这只是一个优先级,代码虽然设置了不过期,但是如果web.xml或者tomcat的配置文件中设置了有效期的话,
还是会过期。所以需要去掉web.xml和tomcat里关于session过期的配置。
Session何时生效
Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
Session何时失效 1.服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。 2.调用Session的invalidate方法。 HttpSession session = request.getSession(); session.invalidate();//注销该request的所有session
3.session的过期时间是从什么时候开始计算的?是从一登录就开始计算还是说从停止活动开始计算? 答:从session不活动的时候开始计算,如果session一直活动,session就总不会过期。 从该Session未被访问,开始计时; 一旦Session被访问,计时清0; 4.设置session的失效时间 a)web.xml中 <session-config> <session-timeout>30</session-timeout> </session-config> b)在代码中手动设置 session.setMaxInactiveInterval(30 * 60);//设置单位为秒,设置为-1永不过期 request.getSession().setMaxInactiveInterval(-1);//永不过期 c)tomcat也可以修改session过期时间,在server.xml中定义context时采用如下定义: <Context path="/livsorder" docBase="/home/httpd/html/livsorder" defaultSessionTimeOut="3600" isWARExpanded="true" isWARValidated="false" isInvokerEnabled="true" isWorkDirPersistent="false"/>
解决方案一:基于Tomcat的session复制
这个解决方案其实就是当用户请求的时候,把产生的sessionID给复制到系统所有的服务器中,这样就能保证当用户请求的时候从服务器A可能调用到服务器B上的模块的时候,也能保证服务B也有该用户的sessionID,这样就不会再次让用户进行再次登录操作了。也就解决问题了。
具体代码中如何实现session复制呢?
使用session复制的优缺点:
---------------------
解决方案二:Spring Session基于Redis做session统一缓存
Spring session设计思路:替换掉Servlet容器创建和管理HttpSession的实现
遇到过的我问题:
随后与客户联系发现,网络中有一个Nginx把cookie过滤掉了。所以请求到达服务器端根本就没了cookie,所以不可能找到session,因此只能创建新的session了。
因客户的网络很难调整,幸运的是spring session支持把session id放入header中传输,至此问题得以解决。
spring session支持多种session的存储介质,当然用的最多的应该还是redis。大家都知道长时间不操作的话session是会过期的。我们第一个想到的就是redis的key也支持过期时 间啊。
只要把session的过期时间设置成redis的TTL,在访问session时更新这个TTL就行了。当你不访问时,TTL逐渐减少到0,key过期,session也就过期了,看似很不错。
使用Redis实现session共享的优缺点:
Nginx session 共享单点登录
JWT Token实现单点登录(生成令牌)(不太推荐:原因jwt具有一次性的特性)
Shiro实现 单点登录https://blog.csdn.net/liuchuanhong1/article/details/76850181#commentBox
Oauth2实现 单点登录https://www.cnblogs.com/cjsblog/p/10548022.html
使用session保存用户登录状态(实现单点登录)https://blog.csdn.net/a605135705/article/details/79021546#commentBox,不是使用服务端自动创建的session(Tomcat),而是自定义session(Httpsession)
用户登录成功,服务端会保存一个session,当然会给客户端一个sessionId把sessionId保存在cookie中,每次请求都会携带这个sessionId,session在服务端保存(数据库或nosql数据库)
Cookie实现单点登录
Cookie在客户端的两种状态:
第一种:持久 cookie 具有时效性,以文件的形式存放在客户机硬盘中,时间一到生命周期结束自动被删除。
第二种:临时 cookie 又叫会话 cookie 放在浏览器内存中,浏览器关闭生命周期结束自动失效 ”。
cookie实现流程: 对服务端请求完成登录时,响应返回一个登录成功标识(类似Token)存入客户端cookie,其他子系统对服务器请求是携带这个Cookie完成登录
注:cookie必须是在同一服务器中有效(同一电脑同一域名及ip),否则子系统获取不到cookie的