cookies 设置未成功情况分析
1,问题描述:
用户登录之后,页面一直刷新,页面呈现空白,jessionId一直在变
http://dev.cbs.abc.com/base/;JSESSIONID=07fa59d4-822e-43a7-ad7f-f0f5f5d2c347
后端显示错误
[2019-03-11 19:16:59,411] INFO com.wiwj.abc.common.shiro.ShiroSession[32] - 调用ShiroSession方法 [2019-03-11 19:16:59,411] INFO com.wiwj.abc.common.shiro.ShiroSession[51] - 调用setId方法 [2019-03-11 19:16:59,411] INFO com.wiwj.abc.common.shiro.ShiroSession[72] - 调用setTimeout方法 [2019-03-11 19:16:59,412] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,413] INFO com.wiwj.abc.common.shiro.ShiroSession[86] - 调用setAttributes方法 [2019-03-11 19:16:59,415] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,418] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,421] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,423] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,426] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,431] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,434] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,456] INFO com.wiwj.abc.common.shiro.ShiroSession[32] - 调用ShiroSession方法 [2019-03-11 19:16:59,456] INFO com.wiwj.abc.common.shiro.ShiroSession[51] - 调用setId方法 [2019-03-11 19:16:59,457] INFO com.wiwj.abc.common.shiro.ShiroSession[72] - 调用setTimeout方法 [2019-03-11 19:16:59,458] INFO com.wiwj.abc.common.shiro.ShiroSession[93] - 调用setAttribute方法 [2019-03-11 19:16:59,458] INFO com.wiwj.abc.common.shiro.ShiroSession[86] - 调用setAttributes方法
2,问题分析,系统框架采用spring+shiro方式,其中shiro配置中jsessionid配置如下
<property name="sessionIdCookie"> <bean class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="sid" /> <property name="domain" value=".cbs.abc.com" /> <property name="path" value="/" /> <property name="maxAge" value="-1" /> <property name="httpOnly" value="true" /> </bean> </property>
而对应的注释为
sessionIdCookie是sessionManager创建会话Cookie的模板: sessionIdCookie.name:设置Cookie 名字,默认为JSESSIONID; sessionIdCookie.domain:设置Cookie的域名,默认空,即当前访问的域名; sessionIdCookie.path:设置Cookie 的路径,默认空,即存储在域名根下; sessionIdCookie.maxAge:设置Cookie 的过期时间,秒为单位,默认-1 表示关闭浏览器时 过期Cookie; sessionIdCookie.httpOnly:如果设置为true,则客户端不会暴露给客户端脚本代码,使用 HttpOnly cookie有助于减少某些类型的跨站点脚本攻击;此特性需要实现了Servlet 2.5 MR6 及以上版本的规范的Servlet容器支持; sessionManager.sessionIdCookieEnabled:是否启用/禁用Session Id Cookie,默认是启用的; 如果禁用后将不会设置Session Id Cookie,即默认使用了Servlet容器的JSESSIONID,且通 过URL重写(URL中的“;JSESSIONID=id”部分)保存Session Id。
看到JsessionId一直在刷新,而这个配置主要是为了设置浏览器的cookies值,由此猜测jsessionId一直刷新的原因是cookies值一直设置不了
另外通过浏览器开发者模式中观察到application-->Storage -->Cookies中的sid存在两个,一个域名为.cbs.xx.com,一个域名为.xx.com
我大胆的把第二个域名.xx.com的这个sid给去掉,然后刷新页面就可以了
3,根源分析
是由于domain域名设置重复的问题,由于之前设置过.abc.com这个域名的sid,再使用.cbs.abc.com这个域名访问时就出现sid设置失败的情况,这个可能跟chrome浏览器设置cookies的机制有关,
其实如果domain都改成.abc.com这种其实也是不行的
建议方案:1,domain这个值都设置成.cbs.abc.com这种访问
2,各个环境设置不同的domain,比如dev.cbs.abc.com,sit.cbs.abc.com;
另外参考往上的cookies的设置规则,以供学习
1)二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其他二级域名domain的cookie。所以要想cookie在多个二级域名中共享,需要设置domain为顶级域名,这样就可以在所有二级域名里面或者到这个cookie的值了。
2)顶级域名只能获取到domain设置为顶级域名的cookie,其他domain设置为二级域名的无法获取。