玄铁剑

成功的途径:抄,创造,研究,发明...
posts - 128, comments - 42, trackbacks - 0, articles - 174

防止重复登陆控制方案

Posted on 2008-01-20 18:34 玄铁剑 阅读(900) 评论(2)  编辑 收藏 引用 所属分类: ASP.NET相关


方案一:

In web.config (StateServer mode, with a one minute timeout to make testing easier):

<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password=letmein"
cookieless="false"
timeout="1"
/>

 

In Global.asax.cs:

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
// Let's write a message to show this got fired---
Response.Write("SessionID: " +Session.SessionID.ToString() + "User key: " +(string)Session["user"]);
if(Session["user"]!=null) // e.g. this is after an initial logon
{
string sKey=(string)Session["user"];
// Accessing the Cache Item extends the Sliding Expiration automatically
string sUser=(string) HttpContext.Current.Cache[sKey];
}
}

 

In your Login Page "Login" button handler:

private void Button1_Click(object sender, System.EventArgs e)
{
//validate your user here (Forms Auth or Database, for example)
// this could be a new "illegal" logon, so we need to check
// if these credentials are already in the Cache

string sKey=TextBox1.Text+TextBox2.Text;
string sUser=Convert.ToString(Cache[sKey]);
if (sUser==null || sUser==String.Empty){
// No Cache item, so sesion is either expired or user is new sign-on
// Set the cache item and Session hit-test for this user---

TimeSpan SessTimeOut=new TimeSpan(0,0,HttpContext.Current.Session.Timeout,0,0);
HttpContext.Current.Cache.Insert(sKey,sKey,null,DateTime.MaxValue,SessTimeOut,
   System.Web.Caching.CacheItemPriority.NotRemovable,null);
Session["user"]=TextBox1.Text+TextBox2.Text;
// Let them in - redirect to main page, etc.
Label1.Text="<Marquee><h1>Welcome!</h1></marquee>";

}
else
{
// cache item exists, so too bad...
Label1.Text="<Marquee><h1><font color=red>ILLEGAL LOGIN ATTEMPT!!!</font></h1></marquee>";
return;
}


}

 


方案二:

public virtual void Application_Start(object sender, EventArgs e) 

// reset the mailer indicator 
Application["MailerStatus"] = "All Mailings Complete"; 

// initialize a datatable for users online 
DataTable objUserTable = new DataTable(); 
objUserTable.Columns.Add("SessionID",System.Type.GetType("System.Guid")); 
objUserTable.Columns.Add("PeopleID",System.Type.GetType("System.Int32")); 
objUserTable.Columns.Add("ShowDetail",System.Type.GetType("System.Boolean")); 
DataColumn[] pk = new DataColumn[1]; 
pk[0] = objUserTable.Columns[0]; 
objUserTable.PrimaryKey = pk; 
Application["UserTable"] = objUserTable; 

/**//// 
/// The Session_Start event adds user session information to 
/// Application["UserTable"]. 
/// 
public virtual void Session_Start(object sender, EventArgs e) 

Application.Lock(); 
//Application.Lock (); 
DataTable objUserTable = (DataTable)Application["UserTable"]; 
DataRow objRow = objUserTable.NewRow(); 
Guid objGuid = Guid.NewGuid(); 
objRow[0] = objGuid; 
Session["PfSessionID"] = objRow[0]; 
objRow[1] = 0; 
objRow[2] = false; 
objUserTable.Rows.Add(objRow); 
Application["UserTable"] = objUserTable; 
Application.UnLock(); 


/**//// 
/// The Session_End event deletes user session information from 
/// Application["UserTable"]. 
/// 
public virtual void Session_End(object sender, EventArgs e) 

Application.Lock(); 
DataTable objUserTable = (DataTable)Application["UserTable"]; 
objUserTable.Rows.Find((Guid)Session["PfSessionID"]).Delete(); 
Application["UserTable"] = objUserTable; 
Application.UnLock(); 
}


方案三:
    protected void Login_Click(object sender, EventArgs e)
    {
        try
        {
            //用户名
            string sName = TextBox1.Text;

            //生成Key  
            string sKey = sName + "_Login";
           
            //得到Cache中的给定Key的值  
            string sUser = Convert.ToString(Cache[sKey]);

            //检查是否存在  
            if (sUser == null || sUser == String.Empty)
            {
                Session["username"] = sName;

                //Cache中没有该Key的项目,表明用户没有登录,或者已经登录超时     
                //TimeSpan 表示一个时间间隔,获取系统对session超时作的设置值
                //(如果考虑到允许用户再次登陆的时间小于session超时时间,可将此值设小) 
                //TimeSpan SessTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);
                //这里为了演示,把Cache保存时间间隔设置为了20秒
                TimeSpan SessTimeOut = new TimeSpan(0, 0, 0, 20, 0);
                HttpContext.Current.Cache.Insert(
                                                    sKey,
                                                    sKey,
                                                    null,
                                                    DateTime.MaxValue,
                                                    SessTimeOut,
                                                    System.Web.Caching.CacheItemPriority.NotRemovable,
                                                    null
                                                 );
               
                //启动Timer
                this.Timer1.Enabled = true;

Label1.Text = "你好!" + sName + "欢迎光临";
            }
            else
            {
                //在Cache中发现该用户的记录,表示已经登录过,禁止再次登录  
                Label1.Text = "对不起,你的用户身份已登陆";
                return;
            }
        }
        catch (System.Exception ex)
        {
            Label1.Text = ex.Message;
        }
    }
    protected void Logout_Click(object sender, EventArgs e)
    {
        //用户名
        string sName = TextBox1.Text;

        //生成Key  
        string sKey = sName + "_Login";

        //为了测试方便,设置了这个从Cache中移出登陆信息的方法
        HttpContext.Current.Cache.Remove(sKey);

        Label1.Text = Session["username"] + " 的用户登陆信息已从Cache清除!";
    }

    protected void TimerRunning_Tick(object sender, EventArgs e)
    {
        if (Session["username"] != null)
        {
            //用户名
            string sName = TextBox1.Text;

            //生成Key  
            string sKey = sName + "_Login";

            //得到Cache中的给定Key的值  
            string sUser = Convert.ToString(Cache[sKey]);

            TimeSpan SessTimeOut = new TimeSpan(0, 0, 0, 20, 0);
            if (sUser != null)
            {
                HttpContext.Current.Cache.Remove(sKey);
            }
            HttpContext.Current.Cache.Insert(
                                                sKey,
                                                sKey,
                                                null,
                                                DateTime.MaxValue,
                                                SessTimeOut,
                                                System.Web.Caching.CacheItemPriority.NotRemovable,
                                                null
                                             );
        }
        else
        {
            this.Timer1.Enabled = false;
        }
    }


Feedback

# re: 防止重复登陆控制方案  回复  更多评论   

2008-06-07 21:13 by air
这个写了又怎么用呢

# re: 防止重复登陆控制方案  回复  更多评论   

2008-06-12 11:10 by 玄鐵劍
這幾個方案不怎麼樣,我也沒有採用這個方式。我在數據庫中建立了Session,並加入了UserID,通過其它方式做到異常斷線後也可以登陸和控制用戶唯一登陸的。
只有注册用户登录后才能发表评论。