asp.net实现同一用户只能在在一个地方登录即单点登录

来源:互联网 发布:数据字典生成工具 编辑:程序博客网 时间:2024/04/30 07:44
Web 项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中;登陆后的用户名放到Session中;登陆后的用户名放到Application中;登陆后的用户名放到Cache中。一般的这几种方法都是登陆了之后,如果没有正常退出,第二次登陆将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登陆的时候,因为Session没有过期等问题,会被拒绝继续登陆系统,只能等待Session过期后才能登陆。本文介绍的方法是第二次登陆时会把第一次的登陆注销掉,第一次登陆将会提示信息:您的帐号已另一地点登录,您被强迫下线的提示信息。
功能实现代码:
1.登录之后调用下面代码
//获取当前项目存储的登录用户sessionid与用户idHashtable hOnline = (Hashtable)Application["Online"]; if (hOnline != null && hOnline.Count > 0){IDictionaryEnumerator idE = hOnline.GetEnumerator();     string strKey = "";     while (idE.MoveNext())     {      //判断当前用户是否已经登录,如果已经登录,上次登录用户的用户id置为特殊内容,便于后面判断是否已经登录过,本项目中使用了“XXXXXX”      if (idE.Value != null && idE.Value.ToString().Equals(model.usrid.ToString()))      {      strKey = idE.Key.ToString();           hOnline[strKey] = "XXXXXX";     break;      }      }}else{hOnline = new Hashtable();}//记录当前登录用户的sessionid以及value值hOnline[Session.SessionID] = model.usrid.ToString();//修改ApplicationApplication.Lock();Application["Online"] = hOnline;Application.UnLock();
2.每一个页面重写或者OnInit方法,本项目中是写在了基类中,每一个页面继承了基类:
protected override void OnInit(EventArgs e){
 Hashtable hOnline = (Hashtable)Application["Online"];                if (hOnline != null && hOnline.Count > 0)                {                    IDictionaryEnumerator idE = hOnline.GetEnumerator();                    while (idE.MoveNext())                    {                        if (idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))                        {                            //already login                            if (idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))                            {                                hOnline.Remove(Session.SessionID);                                Application.Lock();                                Application["Online"] = hOnline;                                Application.UnLock();                                Response.Write("<Script Language=Javascript>alert('您的帐号已在另一地点登录,您被迫下线!');</Script>");
//url为需要调整的页面                                Response.Write("<Script Language=Javascript>window.top.location.href='" + url + "';</Script>");                                Response.End();                                return;                             }                         }                    }                }
}
3.当前用户session超时,需要清除当前用户的信息(本项目中是将方法提取出来,再global文件中调用):
      /// <summary>        /// Global文件的SessionEnd事件中增加此代码        /// </summary>        public static void GlobalSessionEnd()        {            Hashtable hOnline = (Hashtable)System.Web.HttpContext.Current.Application["Online"];            if (hOnline[System.Web.HttpContext.Current.Session.SessionID] != null)            {                hOnline.Remove(System.Web.HttpContext.Current.Session.SessionID);                System.Web.HttpContext.Current.Application.Lock();                System.Web.HttpContext.Current.Application["Online"] = hOnline;                System.Web.HttpContext.Current.Application.UnLock();            }        }
4.global文件中调用上面的方法:
protected void Session_End(Object sender, EventArgs e)
{          GlobalSessionEnd();}
5.当用户正常退出时,在退出对应的事件中调用上面的方法;
GlobalSessionEnd();
                                             
0 0