天天看點

Asp.net實作踢出使用者

最近公司老大叫我實作防止使用者重複登入的功能,既然是老大吩咐的那肯定要去做了,哈哈,開個玩笑,言歸正傳吧。到網上找了很多資料,大部分都用Application或資料庫實作,其原理我就不用多說了,想必大家都知道,一開始想起來很以為很簡單,開始到了後面就很棘手了,為什麼呢,應為用Application或資料庫實作的原理是:當使用者正常登入的時候把使用者名加到Application裡或在資料庫表裡加個字段設定為1表示登入,在使用者退出的時候把Application裡的使用者資訊清除或把資料庫表裡的字段設定成0,但是我們怎麼知道使用者是怎麼樣退出的呢,點浏覽器的x或斷電等等我們都無法把Application裡的使用者資訊清除或把資料庫表裡的字段設定成0。另外有種做法是當使用者正常登入的時候每隔x時間去更新使用者最好活動的時間,然後用時間間隔來判斷使用者是否線上,大于x時間表示使用者退出了(不管是怎麼退出都行),不過這樣的做法對于小型伺服器隻能是望而止步了,應為性能消耗是可想而知的。

我的想法是:既然要防止使用者重複登入,如果有兩個使用者登入了,把前面一個給踢出去那不也符合需求嗎?呵呵

而且這樣也比較好做,不知道大家的想法是不是這樣。現在把代碼貼出來分享下(有些是引用别人寫的)

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
           
namespace LBC.Web.Modulers
{
    /// 
    /// ISingleLogin 接口,提供一組實作單點登入的方法和屬性
    /// 
    public interface ISingleLogin
    {
        /// 
        /// 擷取使用者名
        /// 
        string SigleUserLoginId { get; }
           
        /// 
        /// 取消目前會話
        /// 
        void SigleUserLogout();
           
    }
           
    /// 
    /// ISingleLoginByCookie接口,提供一組用Cookie實作單點登入的方法和屬性
    /// 
    public interface ISingleLoginByCookie : ISingleLogin
    {
        /// 
        /// 擷取Cookie儲存的值,該值為目前時間的刻度數
        /// 
        string CookieValue { get;}
    }
           
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (GetCookieValue("UserId") == "")//為空表示使用者沒有登入
            {
                Response.Redirect("login.aspx");
            }
        }
           
        /// 
        /// 擷取Cookie中的值
        /// 
        /// 儲存該值的鍵
        /// 
        private string GetCookieValue(string KeyName)
        {
            if (string.IsNullOrEmpty(KeyName)) return "";
            if (this.Context.Request.Cookies != null)
            {
                if (this.Context.Request.Cookies["UserCookie"] != null)
                {
                    HttpCookie cookie = this.Context.Request.Cookies["UserCookie"];
                    return cookie[KeyName];
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }
           
        #region ISingleLogin 成員
           
        /// 
        /// 擷取使用者名
        /// 
        public string SigleUserLoginId
        {
            get
            {
                return this.GetCookieValue("UserId");//使用者名
            }
        }
           
        /// 
        /// 取消目前會話
        /// 
        public void SigleUserLogout()
        {
            RemoveCookie();//移除cookie
            Session.Abandon();//取消目前會話
            Response.Write("你在别處已經登陸,強制退出本次登陸!");
        }
           
        /// 
        /// 移除cookie
        /// 
        private void RemoveCookie()
        {
            HttpCookie cookie = new HttpCookie("UserCookie");
            cookie.Expires = DateTime.Now.AddDays(-1);
            this.Context.Response.Cookies.Add(cookie);
        }
           
        #endregion
           
        #region ISingleLoginByCookie 成員
           
        /// 
        /// 擷取Cookie儲存的值,該值為目前時間的刻度數
        /// 
        public string CookieValue
        {
            get
            {
                return this.GetCookieValue("TimeTick");
            }
        }
           
        #endregion
    }
           
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (Session["UserId"] == null)//為空表示使用者沒有登入
            {
                //Response.Write("你還沒有登陸");
                Response.Redirect("login.aspx");
            }
        }
           
        #region ISingleLogin 成員
           
        /// 
        /// 擷取使用者名
        /// 
        public string SigleUserLoginId
        {
            get
            {
                return Session["UserId"] == null ? "" : Session["UserId"].ToString();//使用者名
            }
        }
           
        /// 
        /// 取消目前會話
        /// 
        public void SigleUserLogout()
        {
            Session.Abandon();//取消目前會話
            Response.Write("你在别處已經登陸,強制退出本次登陸!");
        }
           
        #endregion
    }
           
        #region IHttpModule 成員
           
        }
           
        public void Init(HttpApplication context)
        {
            context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
        }
           
        #endregion
           
        public abstract void context_PreRequestHandlerExecute(object sender, EventArgs e);
           
    }
    /// 
    /// 用"Session"實作使用者單點登入的類
    /// 
    public class SingleLoginBySession : SingleLoginModuler
    {
        /// 
        /// 重寫父類的方法
        /// 
        /// 
        /// 
        public override void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;//擷取目前HttpApplication對象
            IHttpHandler httpHandler = application.Context.CurrentHandler;//擷取目前IHttpHandler對象
            ISingleLogin SingleLogin = httpHandler as ISingleLogin;//轉換成ISingleLogin接口,判斷有沒實作該接口
           
            //是否繼承了ISingleLogin接口
            if (SingleLogin != null)
            {
                //目前Session是否存在 
                if (application.Session != null)
                {
                    //擷取使用者名
                    string UserId = SingleLogin.SigleUserLoginId;
                    //使用者是否登入 
                    if (string.IsNullOrEmpty(UserId))
                    {
                        //擷取使用者登入的SessionID,在登入頁面設定,并判定兩個ID是否是相同的,不同則表示後來有人用你的帳号登入
                        if (application.Application["Session" + UserId].ToString() != application.Session.SessionID)
                        {
                            //綁定頁面初始化開始時發生的事件
                            Page page = (Page)httpHandler;
                            page.PreInit += new EventHandler(page_PreInit);
           
                        }
                    }
                }
            }
        }
           
        /// 
        /// 頁面初始化開始調用的方法
        /// 
        /// 
        /// 
        void page_PreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;
            ISingleLogin sl = page as ISingleLogin;
            if (sl != null)
            {
                sl.SigleUserLogout();
                page.Response.End();
            }
        }
    }
           
        public override void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;//擷取目前HttpApplication對象
            IHttpHandler httpHandler = application.Context.CurrentHandler;//擷取目前IHttpHandler對象
            ISingleLoginByCookie SingleLogin = httpHandler as ISingleLoginByCookie;//轉換成ISingleLogin接口,判斷有沒實作該接口
           
            //是否繼承了ISingleLoginByCookie接口且目前Cookies是否存在 
            if (SingleLogin != null && application.Response.Cookies != null)
            {
                string UserId = SingleLogin.SigleUserLoginId;//擷取使用者名
                string TimeTick = SingleLogin.CookieValue;//擷取目前時間的刻度數
           
                //判斷使用者是否登入且目前時間的刻度數是否為空
                if (string.IsNullOrEmpty(UserId) && string.IsNullOrEmpty(TimeTick))
                {
                    return;
                }
                else
                {
                    if (application.Application["Cookie" + UserId] != null)
                    {
                        //擷取使用者登入時儲存在Cookie中的目前時間的刻度數,在登入頁面設定,并判定兩個目前時間的刻度數是否是相同的,
                        //不同則表示後來有人用你的帳号登入
                        if (application.Application["Cookie" + UserId].ToString() != TimeTick)
                        {
                            //綁定頁面初始化開始時發生的事件
                            Page page = (Page)httpHandler;
                            page.PreInit += new EventHandler(page_PreInit);
           
                        }
                    }
                }
            }
        }
           
        /// 
        /// 頁面初始化開始調用的方法
        /// 
        /// 
        /// 
        private void page_PreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;
            ISingleLoginByCookie SingleLogin = page as ISingleLoginByCookie;
            if (SingleLogin != null)
            {
                SingleLogin.SigleUserLogout();
                page.Response.End();
            }
        }
    }
} 
           
以上是我寫的所有的代碼,用兩種方法實作,本機測試成功