很神奇,F0.jsp上有个登陆链接,/U2Prelog.do,在这个Action中saveToken,
并跳转到FB0.jsp , 在FB0.jsp提交登录表单,执行/U2Login.do , 在此Action中
检查isTokenValid ,如果不valid就跳转到首页。
现在执行完一次登陆后,修改客户端系统时间(客户端与服务器不是一台机器),然后点
登陆链接,再登陆,就提示TokenValid return false .
首先服务器上,U2Login.do 成功登陆后就resetToken.登陆后session.
log.info("login in =======================1111111");
HttpSession session = request.getSession();
log.info("session.id="+request.getSession().getId());
log.info("session.createTime="+request.getSession().getCreationTime());
log.info("session.getLastAccessedTime="+request.getSession().getLastAccessedTime());
String saved = (String) session.getAttribute(org.apache.struts.Globals.TRANSACTION_TOKEN_KEY);
log.info("session.token="+saved); // session中的token.
String token = request.getParameter(org.apache.struts.taglib.html.Constants.TOKEN_KEY);
log.info("request.token="+token); // request中的token.
log.info("login in =======================2222222");
记录日志如下;
- login in =======================1111111
- session.id=1E22DF41F6D01061743AEB9AA277E9A9
- session.createTime=1132628191081
- session.getLastAccessedTime=1132628308880
- session.token=null
- request.token=9586a22818378c34a75329a160021529
- login in =======================2222222
之后的代码:
if (!this.isTokenValid(request)) {
// repeated login
}else{
resetToken(request); // 登陆成功后把session中的token清空
}
修改了系统时间后,删除缓存就能执行正常.于是我就注意缓存问题,当系统时间使用之前的时间时,Windows系统
使用缓存而不是发送新的请求,这是关键的一个知识点.
我发现,F0.jsp上点/U2Prelogin.do 并没有进入U2PreLoginAction.java类,而是直接跳到FB0.jsp
原来是客户端缓存了FB0.jsp,所以客户端的token还是上次登陆的token,而服务器上的session中的token已经
清掉了,正如log中两行红字所示,会造成“重复登陆的假象”。
解决办法:别把FB0.jsp缓存到客户端就可以了,那么如何去掉缓存呢?
Struts已经配置了不要缓存,
<controller nocache="true" inputForward="true" maxFileSize="100M"/>
所以只需要把页面上的,
<%
//response.setHeader("Cache-Control", "Public");//把这句话注释掉就行
%>
,这样只修改了FB0.jsp就解决了这个诡异的问题.