JSP唯一登录及踢人的解决方案
2007-07-01 10:01
141 查看
1.问题描述
同一个帐号只允许一个人登录,在有其他用户登录的时候,给予原登录用户警告提示。
2.分析设计
原问题分解成2个小问题:A. 唯一登录;B.踢人
A.
(1)第一次发生登录行为的时候的时候将用户信息及sessionId存放到一个实体Bean里,并将这个bean保存到session中。同时以该用户帐号account作为key,帐号对应的sessionId作为值,存到一个Hashtable比如ht里面,并把这个ht保存到ServletContext(暨application)里面永久保存。
(2)再次发生登录行为的时候,同样首先把用户信息及其sessionId存到实体Bean里面并保存到session。然后从ServletContext里面取出ht,以account做为查询条件判断ht里面是否包含着这个值。如果包含并且其对应的sessionId与当前session里面保存的实体Bean所带的sessionId相同的话,则验证通过,用户的登录是有效的;否则ht里面包含account值但sessionId与session里面保存的bean所带的sessionID不同,则表明发生了同一账户登录行为,将原来的session注销,并更新ht把新的sessionId存放进去。
(3)实现页面每次刷新都会进行(2)的核对,这样就实现了唯一登录
B:
按道理来说,A已经实现了部分的踢人原理,因为原登录用户在刷新页面的时候,就发现自己被注销了session处于未登录状态。但是在这基础上,客户要求发生有人用同一账户登录就立即通知原用户,并中止原用户的一切行为。
初步考虑有两种方案:
(1)线程:启用线程控制登录用户
(2)JavaScript脚本实现:很简单,就是在比较短的时间内,不断的发生刷新页面的行为,进行检测,一旦发生sesionId被更改的情况,就弹出对话框警告用户,并强制刷新页面。
a.页面不断被刷新是很讨厌的事情,出此考虑,在每个页面嵌入一个隐藏的iframe,iframe链接到一个页面,js脚本控制不断刷新iframe页面。这样对于用户来说是不透明的。除了鼠标的闪动之外,用户的页面是不会发生变化的。而且iframe所链接到的页面仅仅涉及到变量检测,无比较耗费时间的检测,服务器的承受力可以接受。
b.在js的控制下,可以设置登录后多少时间提示用户,这个时间越长,比如延长到10秒之后,那么对服务器及用户的映像几乎可以忽略。经测试,5秒中后提示给用户的感觉就是立即被踢下去了。
3.部分源码
初步考虑有两种方案:
登陆时候的操作:
/**
* 用户唯一登陆
* @param mb
* @param session
* @param account
*/
public void setService(memberBean mb, HttpSession session, String account) {
session.setAttribute(sessionName, mb);
if (sc.getAttribute(sessionList) == null) {// 第一次登陆
Hashtable htb = new Hashtable();
htb.put(account, session.getId());
sc.setAttribute(sessionList, htb);
} else {// 第二次登陆后第一次无效
Hashtable htb = (Hashtable) sc.getAttribute(sessionList);
String key = null;
if (htb.containsKey(account)) {
//更新session
htb.remove(account);
}
htb.put(account, session.getId());
sc.setAttribute(sessionList, htb);
}
}
唯一检测:
/**
* 检测用户是否登陆
* @param session
* @param account
* @return
*/
public boolean checkLogin(HttpSession session,String account) ;
iframe的控制:
<script language="JavaScript" type="text/javascript">
<!--
var counter;
function iCheckCount() {
nowTime = new Date().getTime();
window.frames["iCheck"].src="iCheck.jsp?"+nowTime;
window.frames["iCheck"].window.location.reload();
counter=setTimeout("iCheckCount()", 5000);
}
function stopTimer() {
clearTimeout(counter);
}
function startTimer() {
counter=setTimeout("iCheckCount()", 5000);
}
//-->
</script>
4.总结及优化
踢人的解决方案里,调用了IE窗口的不断刷新,虽然动作行为被隐藏,但是还是存在的。除此之外能不能在线程里做到与客户端交互,彻底的隐藏检测行为,并能够在发生同样登录的情况下唤醒线程,控制客户端窗口,是值得考虑的问题。
欢迎大家留言讨论。
同一个帐号只允许一个人登录,在有其他用户登录的时候,给予原登录用户警告提示。
2.分析设计
原问题分解成2个小问题:A. 唯一登录;B.踢人
A.
(1)第一次发生登录行为的时候的时候将用户信息及sessionId存放到一个实体Bean里,并将这个bean保存到session中。同时以该用户帐号account作为key,帐号对应的sessionId作为值,存到一个Hashtable比如ht里面,并把这个ht保存到ServletContext(暨application)里面永久保存。
(2)再次发生登录行为的时候,同样首先把用户信息及其sessionId存到实体Bean里面并保存到session。然后从ServletContext里面取出ht,以account做为查询条件判断ht里面是否包含着这个值。如果包含并且其对应的sessionId与当前session里面保存的实体Bean所带的sessionId相同的话,则验证通过,用户的登录是有效的;否则ht里面包含account值但sessionId与session里面保存的bean所带的sessionID不同,则表明发生了同一账户登录行为,将原来的session注销,并更新ht把新的sessionId存放进去。
(3)实现页面每次刷新都会进行(2)的核对,这样就实现了唯一登录
B:
按道理来说,A已经实现了部分的踢人原理,因为原登录用户在刷新页面的时候,就发现自己被注销了session处于未登录状态。但是在这基础上,客户要求发生有人用同一账户登录就立即通知原用户,并中止原用户的一切行为。
初步考虑有两种方案:
(1)线程:启用线程控制登录用户
(2)JavaScript脚本实现:很简单,就是在比较短的时间内,不断的发生刷新页面的行为,进行检测,一旦发生sesionId被更改的情况,就弹出对话框警告用户,并强制刷新页面。
a.页面不断被刷新是很讨厌的事情,出此考虑,在每个页面嵌入一个隐藏的iframe,iframe链接到一个页面,js脚本控制不断刷新iframe页面。这样对于用户来说是不透明的。除了鼠标的闪动之外,用户的页面是不会发生变化的。而且iframe所链接到的页面仅仅涉及到变量检测,无比较耗费时间的检测,服务器的承受力可以接受。
b.在js的控制下,可以设置登录后多少时间提示用户,这个时间越长,比如延长到10秒之后,那么对服务器及用户的映像几乎可以忽略。经测试,5秒中后提示给用户的感觉就是立即被踢下去了。
3.部分源码
初步考虑有两种方案:
登陆时候的操作:
/**
* 用户唯一登陆
* @param mb
* @param session
* @param account
*/
public void setService(memberBean mb, HttpSession session, String account) {
session.setAttribute(sessionName, mb);
if (sc.getAttribute(sessionList) == null) {// 第一次登陆
Hashtable htb = new Hashtable();
htb.put(account, session.getId());
sc.setAttribute(sessionList, htb);
} else {// 第二次登陆后第一次无效
Hashtable htb = (Hashtable) sc.getAttribute(sessionList);
String key = null;
if (htb.containsKey(account)) {
//更新session
htb.remove(account);
}
htb.put(account, session.getId());
sc.setAttribute(sessionList, htb);
}
}
唯一检测:
/**
* 检测用户是否登陆
* @param session
* @param account
* @return
*/
public boolean checkLogin(HttpSession session,String account) ;
iframe的控制:
<script language="JavaScript" type="text/javascript">
<!--
var counter;
function iCheckCount() {
nowTime = new Date().getTime();
window.frames["iCheck"].src="iCheck.jsp?"+nowTime;
window.frames["iCheck"].window.location.reload();
counter=setTimeout("iCheckCount()", 5000);
}
function stopTimer() {
clearTimeout(counter);
}
function startTimer() {
counter=setTimeout("iCheckCount()", 5000);
}
//-->
</script>
4.总结及优化
踢人的解决方案里,调用了IE窗口的不断刷新,虽然动作行为被隐藏,但是还是存在的。除此之外能不能在线程里做到与客户端交互,彻底的隐藏检测行为,并能够在发生同样登录的情况下唤醒线程,控制客户端窗口,是值得考虑的问题。
欢迎大家留言讨论。
相关文章推荐
- DEDECMS之唯一登录,踢人效果
- PHP之深度剖析:网站唯一登录,踢人效果
- 网站唯一登录,踢人效果
- java鬼混笔记:shiro 10、在线用户、踢人下线、唯一登录
- 关于Weblogic异常:weblogic.servlet.jsp.compilationException解决方案
- 关于Windows 2008 IIS无法使用虚拟目录密码作为用户 administrator 在本地登录到...解决方案
- Jsp+Servlet+mySQl登录界面实现
- 百度谷歌唯一解决方案--解决jQuery Validation插件 相同名称文本框只验证第一个
- 微信小程序 保持登录状态(自己服务端的session)的解决方案(java)
- jsp中文乱码六种情况---解决方案
- JSP 登录页面
- JSP 登录验证码
- SSO-单点登录完全解决方案
- ios7 上取得设备唯一标志的解决方案
- 基于.Net的单点登录(SSO)解决方案(简易方案以及后续更新成熟方案)
- JSP开发过程遇到的中文乱码问题及解决方案
- JSP和IIS的最佳解决方案实例分析
- Servlet.service() for servlet jsp threw exception java.lang.Il在jsp中使用jspsmartupload组件下载文件时将抛出异常的解决方案
- SSO单点登录解决方案——Filter方式
- 在jsp页面实现保存登录用户名和密码