天天看點

通過SessionID和使用者名來保證同一個使用者不能同時登入

  可以通過SessionID和使用者名來保證同一個使用者不能同時登入的問題,下面程式模仿了QQ的登入,當登入後判斷目前帳号是否已經登入,如果登入。則踢掉以前登入的使用者。

  1.通過Application全局變量來存儲SessionID和使用者名,每次登入時都儲存,并且将該Application存入 Hashtable中,當使用者登入成功後,首先判斷該使用者是否已經存儲在Application中,如果存在(說明已經登入),則将該使用者對應的值設定為 XX(值為無用).

  代碼

輕按兩下代碼全選

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

protected void loginbtn_Click(object sender, EventArgs e)

    {

        //登入成功。。。。。。。

        Hashtable hOnline = (Hashtable)Application["Online"];//讀取全局變量

        if (hOnline != null)

        {

            IDictionaryEnumerator idE = hOnline.GetEnumerator();

            string strKey = "";

            while (idE.MoveNext())

            {

                if (idE.Value != null && idE.Value.ToString().Equals(UserID))//如果目前使用者已經登入,

                {

                    //already login            

                    strKey = idE.Key.ToString();

                    hOnline[strKey] = "XX";//将目前使用者已經在全局變量中的值設定為XX

                    break;

                }

            }

        }

        else

        {

            hOnline = new Hashtable();

        }

        hOnline[Session.SessionID] = UserID;//初始化目前使用者的

        Application.Lock();

        Application["Online"] = hOnline;

        Application.UnLock();

        Response.Redirect("main.aspx");

    }

  2,寫一個BasePage加一個Init方法如下,系統的所有頁面均繼承自該BasePage

  代碼

輕按兩下代碼全選

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

 protected override  void OnInit(EventArgs e)

   {

       Hashtable hOnline = (Hashtable)Application["Online"];//擷取已經存儲的application值

       if(hOnline != null)

       {

        IDictionaryEnumerator idE = hOnline.GetEnumerator();

        while(idE.MoveNext())

        {

             if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))

             {

              //already login

                 if (idE.Value != null && "XX".Equals(idE.Value.ToString()))//說明在别處登入

                  {

                       hOnline.Remove(Session.SessionID);

                       Application.Lock();

                       Application["Online"] = hOnline;

                       Application.UnLock();

                       Response.Write("<

script

>alert('你的帳号已在别處登陸,你被強迫下線!');top.location.href='Default.aspx';window.close();</

script

>");//退出目前到登入頁面

                      // Response.Redirect("Default.aspx");

                       Response.End();

                     //  return false;

                  }

                 

                  //break;

             }

            

        }

   }

  3.在程式退出後從Application中清除目前SessionID

  代碼

輕按兩下代碼全選

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

void Session_End(object sender, EventArgs e) 

    {

        // 在會話結束時運作的代碼。 

        // 注意: 隻有在 Web.config 檔案中的 sessionstate 模式設定為

        // InProc 時,才會引發 Session_End 事件。如果會話模式設定為 StateServer 

        // 或 SQLServer,則不會引發該事件。

        Hashtable hOnline = (Hashtable)Application["Online"];

        if (hOnline[Session.SessionID] != null)

        {

            hOnline.Remove(Session.SessionID);//清除目前SessionID

            Application.Lock();

            Application["Online"] = hOnline;

            Application.UnLock();

        }

 

    }

  4.如果程式非正常退出,SessionID沒有及時的清除,那麼也不會影響帳号的正常登入,而SessionID也會随着Session的過期而自動清除,伺服器也不會有壓力。

  5,如果感覺存儲在Application中感覺不好,也可以将SessionID存入資料庫中,判斷方法和上面一樣。

  6,測試時注意在不同機器上面測試,同一台機子上面的SessionID是一樣的,每次設定為XX後又有新值進去,看不到效果,如果要防止同一個帳号在同一台機子上面同僚登入兩次以上,可以通過mac位址來判斷。

c#