如何实现单一用户单一机子登录
2013-08-01 10:40
471 查看
1、要解决同一台电脑上只允许有一个用户登录系统,只有一个办法。监视每一个连接的来源,如果发现有一个新的连接与某个已经存在的连接来自同一台电脑,则终止其中的一个(当然,也可以提醒用户,让他自己决定终止哪一个)。
2、要禁止一个用户账号同时在不同的客户端登录,只有监视每一个连接的用户账号,如果发现一个新连接的用户账号跟某个已经存在的连接的用户账号相同,则自动将前一个终止(同样,也可以让用户自己决定终止哪一个)。
确定了基本思路以后,就要找具体办法了。我最初的想法是在数据库建立一张表,存放已登录用户的用户名、物理地址、Session id等信息。当用户登录时,与这张表里面的数据进行匹配,如果发现物理地址与表中的某条记录相同,则表示是同一台客户端上有多个用户再登录,如果发现正在登录的用户的用户名与表中已有记录相同而主机名不同,则表示是一个账号同时在不同的客户端使用。
相信很多一开始遇到这个问题的人都会考虑这种解决办法。但是这种办法有很多问题,最主要的问题有两个:第一是效率,每一次都要从数据库里面取数据进行匹配。第二是用户退出时需要删除表中的记录,而当用户非正常退出时,很难及时监测(后来发现其实有办法监测)。
后来在网上的某个帖子里面看到一位大侠提到用监听器,只是那位大侠说的太含糊,照他说的办法根本无法解决。虽然无法解决,但是提供了一个思路。于是我找了一本书,仔细看了其中关于监听器的部分。解决办法就在其中了!!!
监听器的详细介绍见我的下一篇博文,这里先把解决办法告诉大家:
监听器可以监听Session及其所包含的属性,即Attribute。
所以我们要做的就是:
1、建立一个监听器,实现HttpSessionAttributeListener接口,监听每一个Attribute的增加、编辑、删除事件。监听器中还要建立一个map,将所有的session放入这个map中。
2、在用户登录时将用户名、物理地址、Session id存到Session中去(可以建立一个用户登录地址数据传输对象,我建立了一个UserSessionAdd类,里面包含username,macAdd,sessionId三个属性,用户登录时将这个数据对象初始化,并存入到session中)。
3、每个新会话开启时,在监听器中对Session包含的属性进行判断,如果新增的属性与map中已有session的用户登录地址数据相同,则表示新会话与我们要做的两个限制相冲突。将与之冲突的会话提取出来,销毁掉!
这么说,还是不够清楚,下面看代码:
[html] view
plaincopyprint?
Web.xml文件:
<listener>
<listener-class>监听器类的路径,如:com.web.MyListener</ listener-class >
</listener>
用户登录地址数据传输对象:
[java] view
plaincopyprint?
publicclass UserSessionAdd {
private Stringadd;
private Stringsessid;
private String username
public String getUsername(){
return username
}
Public void setUsername(String username){
this.username=username;
}
public String getIp() {
returnadd;
}
publicvoid setAdd(String add) {
this.add = add;
}
public String getSessid() {
returnsessid;
}
publicvoid setSessid(String sessid) {
this.sessid = sessid;
}
}
用户登录的代码:
[java] view
plaincopyprint?
···
String userHost = request.getRemoteHost();
String sessionId = request.getSession().getId();
UserSessionAdd usa = new UserSessionAdd();
usa.setUsername(username);
usa.setSessid(sessionId);
usa.setAdd(userHost);
request.getSession().setAttribute(“usa”,usa);
监听器代码:
[java] view
plaincopyprint?
publicclass MyListenerimplementsHttpSessionAttributeListener{
Map<String, HttpSession> map =new HashMap<String, HttpSession>();
publicvoidattributeAdded(HttpSessionBindingEvent event) {
String name = event.getName();
if(name.equals("usa")){
UserSessionAdd usa = (UserSessionAdd)event.getValue();
if(map.get(usa.getAdd())!=null){
HttpSession sess = map.get(usa.getAdd());
UserSessionAdd usa1 = (UserSessionAdd)sess.getAttribute("usa");
sess.removeAttribute("usa");
sess.invalidate();
}
map.put(usa.getAdd(), event.getSession());
}
}
publicvoidattributeRemoved(HttpSessionBindingEvent event) {
String name = event.getName();
if(name.equals("usa")){
UserSessionAdd usa = (UserSessionAdd)event.getValue();
map.remove(usa.getAdd());
}
}
publicvoidattributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
````
}
}
2、要禁止一个用户账号同时在不同的客户端登录,只有监视每一个连接的用户账号,如果发现一个新连接的用户账号跟某个已经存在的连接的用户账号相同,则自动将前一个终止(同样,也可以让用户自己决定终止哪一个)。
确定了基本思路以后,就要找具体办法了。我最初的想法是在数据库建立一张表,存放已登录用户的用户名、物理地址、Session id等信息。当用户登录时,与这张表里面的数据进行匹配,如果发现物理地址与表中的某条记录相同,则表示是同一台客户端上有多个用户再登录,如果发现正在登录的用户的用户名与表中已有记录相同而主机名不同,则表示是一个账号同时在不同的客户端使用。
相信很多一开始遇到这个问题的人都会考虑这种解决办法。但是这种办法有很多问题,最主要的问题有两个:第一是效率,每一次都要从数据库里面取数据进行匹配。第二是用户退出时需要删除表中的记录,而当用户非正常退出时,很难及时监测(后来发现其实有办法监测)。
后来在网上的某个帖子里面看到一位大侠提到用监听器,只是那位大侠说的太含糊,照他说的办法根本无法解决。虽然无法解决,但是提供了一个思路。于是我找了一本书,仔细看了其中关于监听器的部分。解决办法就在其中了!!!
监听器的详细介绍见我的下一篇博文,这里先把解决办法告诉大家:
监听器可以监听Session及其所包含的属性,即Attribute。
所以我们要做的就是:
1、建立一个监听器,实现HttpSessionAttributeListener接口,监听每一个Attribute的增加、编辑、删除事件。监听器中还要建立一个map,将所有的session放入这个map中。
2、在用户登录时将用户名、物理地址、Session id存到Session中去(可以建立一个用户登录地址数据传输对象,我建立了一个UserSessionAdd类,里面包含username,macAdd,sessionId三个属性,用户登录时将这个数据对象初始化,并存入到session中)。
3、每个新会话开启时,在监听器中对Session包含的属性进行判断,如果新增的属性与map中已有session的用户登录地址数据相同,则表示新会话与我们要做的两个限制相冲突。将与之冲突的会话提取出来,销毁掉!
这么说,还是不够清楚,下面看代码:
[html] view
plaincopyprint?
Web.xml文件:
<listener>
<listener-class>监听器类的路径,如:com.web.MyListener</ listener-class >
</listener>
用户登录地址数据传输对象:
[java] view
plaincopyprint?
publicclass UserSessionAdd {
private Stringadd;
private Stringsessid;
private String username
public String getUsername(){
return username
}
Public void setUsername(String username){
this.username=username;
}
public String getIp() {
returnadd;
}
publicvoid setAdd(String add) {
this.add = add;
}
public String getSessid() {
returnsessid;
}
publicvoid setSessid(String sessid) {
this.sessid = sessid;
}
}
用户登录的代码:
[java] view
plaincopyprint?
···
String userHost = request.getRemoteHost();
String sessionId = request.getSession().getId();
UserSessionAdd usa = new UserSessionAdd();
usa.setUsername(username);
usa.setSessid(sessionId);
usa.setAdd(userHost);
request.getSession().setAttribute(“usa”,usa);
监听器代码:
[java] view
plaincopyprint?
publicclass MyListenerimplementsHttpSessionAttributeListener{
Map<String, HttpSession> map =new HashMap<String, HttpSession>();
publicvoidattributeAdded(HttpSessionBindingEvent event) {
String name = event.getName();
if(name.equals("usa")){
UserSessionAdd usa = (UserSessionAdd)event.getValue();
if(map.get(usa.getAdd())!=null){
HttpSession sess = map.get(usa.getAdd());
UserSessionAdd usa1 = (UserSessionAdd)sess.getAttribute("usa");
sess.removeAttribute("usa");
sess.invalidate();
}
map.put(usa.getAdd(), event.getSession());
}
}
publicvoidattributeRemoved(HttpSessionBindingEvent event) {
String name = event.getName();
if(name.equals("usa")){
UserSessionAdd usa = (UserSessionAdd)event.getValue();
map.remove(usa.getAdd());
}
}
publicvoidattributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
````
}
}
相关文章推荐
- 单一用户登录,即当前用户登录后要踢出前一个登录,即做出踢人效果,如何实现?
- phpcms v9 如何实现用户登录
- 如何实现共享软件网络授权认证,包括注册新用户、登录、修改密码等操作
- vsftpd如何实现实名用户登录
- C#笔记1——如何在登录界面设置主界面的ToolStripMenuItem的enabled属性,实现不同用户进入不同模块
- C# Winform中如何实现获取当前用户的网络名和登录名【数据库操作】
- 教你如何配置linux用户实现禁止ssh登陆机器但可用sftp登录!
- normal用户同一时间只能有一个登录session,如何实现多个登录?
- phpcmsv9 如何实现用户登录
- Windows XP 如何修改实现不输入用户密码而直接登录系统
- [原]基于CAS实现单点登录(SSO):登录成功后,cas client如何返回更多用户信息
- Django 是如何实现用户登录和登出机制的(默认版本-数据库版本)
- 如何实现不同权限的用户登录后看到不同的菜单(菜单分两级)
- 过滤器实现单一用户登录
- 利用ajax实现登录:验证完用户信息后如何保存用户信息并实现跳转
- 如何在不跳转的情况下实现用户登录
- [Oracle] 如何使用触发器实现IP限制用户登录
- XP如何实现用户自动登录
- FTP服务器工作原理及如何通过PAM认证实现虚拟用户登录;
- 如何使用触发器实现IP限制用户登录