防止用户重复登陆系统

原创 2006年05月23日 16:03:00

很多系统要求防止用户被重复登陆,我们通常思维是当有用户重复登陆时要禁止他再登陆进去,
提示他该账号已经有人在使用中.
然而这样有个问题很难解决,就是系统很难实时捕捉到该账号是否还在使用中,
如当用户非正常退出或者遇到停电等,系统只好等到Session超时后才能知道该账号已经下线.
在Session超时之前这段时间之内没有人使用账号但也没人再能登陆上去,只能干等着了.

我的解决方法是模仿QQ的被迫下线的功能。只要你QQ号和密码正确,随时都可以登陆上去,但是如果
该QQ号此前有人在使用的话那先前的人就会被挤下去。我们这样来实现系统防止用户重复登陆的话就可以轻松实现。关键就是在Application或数据库中记录下在线用户的SessionID,检测使用者的SessionID是否和Application中记录的该用户ID相对应的SessionID相同,若不相同则提示下线!

用户登陆成功时用户ID和SessionID写入Application中。
 

public void WriteToApplication( string UserID )
  {
   DataTable dtUserFlagList = new DataTable();
   try
   {
    dtUserFlagList = (DataTable)Application["UserFlagList"];
   }
   catch
   {
    dtUserFlagList = null;
   }

   if( dtUserFlagList == null )
   {
    DataColumn dc0 = new DataColumn("UserID",typeof(System.String));
    DataColumn dc1 = new DataColumn("SessionID",typeof(System.String));

    dtUserFlagList.Columns.Add( dc0 );
    dtUserFlagList.Columns.Add( dc1 );
    dtUserFlagList.Columns.Add( dc2 );

    DataRow drUser = dtUserFlagList.NewRow();
    drUser["UserID"] = UserID; //写入用户ID
    drUser["SessionID"] = Session.SessionID;//记录下SessionID

    dtUserFlagList.Rows.Add( drUser );
   }
   else
   {
    int i = 1;
    foreach( DataRow drUser in dtUserFlagList )
    {
     if( drUser["UserID"].ToString() == UserID )
     {
      drUser["SessionID"] = Session.SessionID;//如果在Application中存在当前用户ID,则把记录的SessionID值改为当前的SessionID
      break;
     }
     i++;
    }
    if( i > dtUserFlagList.Rows.Count )
    {
     DataRow drUser = dtUserFlagList.NewRow();
     drUser["UserID"] = UserID; //写入用户ID
     drUser["SessionID"] = Session.SessionID;//记录下SessionID
  
     dtUserFlagList.Rows.Add( drUser );
    }
   }

   Application.Lock();
   Application["UserFlagList"] = dtUserFlagList; //记录到Application中
   Application.UnLock();

   Session["UserID"] = UserID;//把相关登陆信息写入Session
  }

下一步我们只要检测Application中记录的SessionID是否和当前的SessionID相同就可以了
我在这里写了一个页面的基类,每个页面继承这个类。这个类改写OnLoad()事件,加入检测SessionID值
public class PageBase : System.Web.UI.Page
{
 public PageBase()
 {
  //
  // TODO: 在此处添加构造函数逻辑
  //
 }

 protected override void OnLoad(EventArgs e)
 {
  base.OnLoad (e);
  if( ! IsPostBack )
  {
   if( Session["UserID"] == null )
   {
    Response.Redirect("Login.aspx");//没有登陆
    return;
   }
   DataTable dtUserFlagList = (DataTable)Application["UserFlagList"];
   foreach( DataRow drUser in dtUserFlagList )
   {
    if( drUser["UserID"].ToString() == Session["UserID"].ToString() )
    {
     if( drUser["SessionID"].ToString() == Session.SessionID )
      break;//SessionID值相同,没有其他用户登陆
     else
     {
      Session.Abandon();//SessionID不相同,有人在使用该账号,被迫下线
      Response.Redirect("ShowError.aspx?action=该账号已在别处登陆",false);
     }
    }
   }
  }
 } 
}

 当用户正常退出系统或非正常退出Session超时,在Application中清除该账号的记录
 以下代码写在Global.asax.cs文件Session_End方法中
 protected void Session_End(Object sender, EventArgs e)
 {
  if( Session["UserID"] == null )
   return;
  
  DataTable dtUserFlagList = (DataTable)Application["UserFlagList"];
  foreach( DataRow drUser in dtUserFlagList )
  {
   if( drUser["UserID"].ToString() == Session["UserID"].ToString() && drUser["SessionID"].ToString() == Session.SessionID )
   {
    //当UserID和SessionID都和退出用户的值相等时才清除记录。
    drUser.Delete();
    break;
   }
  }
  dtUserFlagList.AcceptChanges();

  Application.Lock();
  Application["UserFlagList"] = dtUserFlagList; //将更改记录到Application中
  Application.UnLock();
 }

 以上方法已经在我的系统中实现,在我的系统可以设定某个账号同时登陆多少人,只是在记录中多了一个字段amount。
 这个方法可能不好的地方就是每访问一个页面都要检测是否SessionID值相等,
 不过我觉得读取Application并不会太大影响系统的效率,这样可以“实时”地检测到用户是否重复登陆

 第一次在CSDN上写博客,水平有限。各位大侠见笑了,欢迎各位指正。zhongqy583@126.com

相关文章推荐

[ASP.NET(C#)] - 解决了防止用户重复登陆和session超时

来源:http://hi.baidu.com/bj1686/blog/item/614b21c6d62813109c163d1c.html 一.设置web.config相关选项先启用窗体身份验证和默认...

防止用户重复登陆和session超时

一.设置web.config相关选项 先启用窗体身份验证和默认登陆页,如下。 authentication mode="Forms"> forms loginUrl="default.asp...

解决了防止用户重复登陆和session超时

一.设置web.config相关选项 先启用窗体身份验证和默认登陆页,如下。   设置网站可以匿名访问,如下   然后设置跟目录下的admin目录拒绝...
  • cuoban
  • cuoban
  • 2016年07月25日 15:43
  • 613

防止用户表单重复提交处理

  • 2017年08月30日 18:29
  • 73KB
  • 下载

防止用户重复登录

  • 2008年06月03日 21:36
  • 3KB
  • 下载

asp.net防止同一帐户重复登陆,查看在线人数

一、新建UserDal文件 namespace Dal { public class UserDal { //获取管理员列表 public ...

Asp.net中防止用户重复登录示例

  • 2012年05月29日 22:08
  • 7KB
  • 下载

springsecurity中如何做到多个用户不能使用同一个账号同时登陆系统

第 8 章 管理会话 多个用户不能使用同一个账号同时登陆系统。 8.1. 添加监听器 在web.xml中添加一个监听器,这个监听器会在session创建和销毁的时...

警惕黑客使用Lion系统漏洞破解和修改用户登陆密码

转载自:http://www.techolics.com/apple/20110922_72.html 9月19日,星期一,名为Patrick Dunstan的黑客公布了如何利用苹果最新Li...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:防止用户重复登陆系统
举报原因:
原因补充:

(最多只允许输入30个字)