这几天为了测试人员测试,就把一个tomcat应用整个拷贝了一份,改了下端口一个8080,一个8081,上下文也一样,结果出问题了:页面登陆验证码死活验证不过去,最后跟踪了下后台发现,登陆界面请求时生成验证码并将验证码放入session里面,这个session的id和验证时从获取验证码的session的的id不一样,那验证的时候由于session不一样,获取验证码肯定为空,最终验证失败。
根据一般的流程,浏览器首次发出请求的时候服务端会在response信息里面给出:
Set-Cookie: JSESSIONID=0000yLsny8JFy4nLxDelrrq9Lx1:-1; Path=/test (这里假设服务器生成的sessionid为0000yLsny8JFy4nLxDelrrq9Lx1,应用上下文为test)要求浏览器设置浏览器会话cookie,下次请求的时候在request头信息里面附带:
Cookie: JSESSIONID=0000yLsny8JFy4nLxDelrrq9Lx1:-1 服务器以此来判断是否统一客户端发出的请求。
而跟踪我们的应用发现第一次浏览器发出请求后,服务端response信息为:
Set-CookieJSESSIONID=C7A2EB23B029226E6279448D1CFD6207; Path=/test
第二次发出请求的时候整个会话信息为:
响应头信息原始头信息:
Set-Cookie: JSESSIONID=AD54301B809A7D7BBF909F10B4C838AA
; Path=/test
请求头信息原始头信息:
Cookie JSESSIONID=4DF629829C6E18953117AB66777ED2CA
浏览器虽然第二次请求带过去的JSESSIONID并不是第一次设置(C7A2EB23B029226E6279448D1CFD6207
),并且服务端又发出了新的Set-Cookie命令和JSESSIONID。
最终才想起还有另一个tomcat应用的copy修改了本次的cookie session 里面的JSESSIONID值,
正好跟踪到信息为:
Set-Cookie JSESSIONID=4DF629829C6E18953117AB66777ED2CA; Path=/test (这一次请求影响)
Cookie JSESSIONID=C7A2EB23B029226E6279448D1CFD6207(原应用的JSESSIONID)
通过查看火狐浏览器里面两个应用在同一个主机(localhost)下面只存了一份名为JSESSIONID的cookie值,结果导致互相影响。
现在tomcat下的一个办法就是两个应用其中一个修改下上下文,例如一个是test,另一个是test1 ,这样由于cookie的路径(path)在同一个级别下名称不一样将不会互相影响。
浏览器判断cookie的应该根据主机,路径,名称来判断,通常根据目录层级不同作用域也不同,例如:
比如浏览器现有三个cookie, path分别为 "/", "/test", "/test/mgr"
则请求 "/test/other/action.do"时,第1个cookie和第2个cookie会被发给服务端,第三个不会。
此时浏览器请求头信息里面的session有可能为多个,但名称都一样如:
Cookie: JSESSIONID=8810E51861891187708C53A1805951A1;JSESSIONID=0000yLsny8JFy4nLxDelrrq9Lx1:-1
这个时候也是出现问题的时候,服务器有可能出现jsessionid不一致的情况,
一个明显的问题在websphere下由于默认的cookie session的path为/ 如图:
这个时候如果同一台主机或者ip下部署其他应用,如果都是用JSESSIONID作为key的话,由于/的作用域大,其他的应用将受到影响,首先websphere自己会受到影响,经过测试websphere的每一次请求如下:
Set-Cookie: JSESSIONID=0000yLsny8JFy4nLxDelrrq9Lx1:-1; Path=/
然后后面多次出现信息如下:
相应
Set-Cookie: JSESSIONID= 0000IsxSqg75ELW4C0Y3YCaRgab
:-1; Path=/
请求
Cookie:
JSESSIONID=8810E51861891187708C53A1805951A1(这个为tomcat的);JSESSIONID=0000yLsny8JFy4nLxDelrrq9Lx1:-1
遇到这种异常情况,请大家从cookie的domain,path,作用域的知识分析下,然后就应该能解决这些问题了,适当的修改下cookie的key名称,和path。
这里给看下百度的明显和其他的不一样用的是(baiduid作为key):
~完~