用户单点登录

      所谓用户单点登录,无非就是同一个用户的帐号同时只能一个人登录。一般情况下这种需求并不需要,但是对于一些视频网站等等之类的收费网站,由于要限制同一帐号只能在同一时间段上一个人。因此就需要用到这块。曾在网上找过相关方面的资料,但是好多都存在这样那样的问题,最致命的问题就是用户非正常退出的情况下,再进行第二次登录的话,需要等好长时间(往往是Session的过期时间,默认情况下20minutes),也有一些人拿这个卖钱。这里所要介绍的主要是处理非正常退出时存在的问题。
    好了,过多的话就不写了,先介绍一下用户单点登录的思路吧,这里我用的仍然是判断用户的Session值。做过用户登录系统的人都知道,在用户登录的同时,会同时为该用户建立一个Session标志,并把该用户的一些信息比如说UserId,UserName写入该Session中,在设置了需要用户权限访问的页面,往往就是通过该Session信息来判断的。当用户正常退出,即点注销或者退出按钮退出的时候,会把该Session信息清空。但是如果不是正常退出,即直接关闭浏览器时,该Session信息仍然存在。这种情况下,如果不做特殊处理的话,做用户单点登录时,会登录不了。也有一些人通过手工缩短Session的生命周期来缩短用户非正常退出情况下二次登录的时间,但是同时引发了另一个问题,即用户登录以后,不刷新页面的情况下,很短的时间内将会提示过期,需要重新登录,因此我感觉做的仍然不是很好。我是在沿用这种思路的情况下,把这块做的更好一些。这里我所使用的是Ajax技术来完善这块。这里需要说明的是,方法有很多种,只是我选择了其中一种。呵呵
    先看看别人写的这段代码(其中修改了一些)
    
 1public static bool AmIOnLine(string userName)
 2    {
 3        string sKey = userName;
 4        // 得到Cache中的给定Key的值
 5        string sUser = Convert.ToString(HttpContext.Current.Cache[sKey]);
 6        // 检查是否存在
 7        if (sUser == null || sUser == String.Empty)
 8        {
 9            // Cache中没有该Key的项目,说明用户没有登录,或者已经登录超时
10            // 注意下面使用的TimeSpan构造函数重载版本的方法,是进行是否登录判断的关键。
11            TimeSpan SessTimeOut = new TimeSpan(000600);
12            HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);
13            System.Web.HttpContext.Current.Session["User"= sKey;
14            // 首次登录,您可以做您想做的工作了。
15            return true;
16        }

17        else
18        {
19            // 在 Cache 中发现该用户的记录,表名已经登录过,禁止再次登录
20            return false;
21        }

22    }
 
23
24    protected void btnLogin_Click(object sender, ImageClickEventArgs e)
25    {
26        // 生成Key
27        string sKey = tbUserName.Text;
28        // 得到Cache中的给定Key的值
29        if (AmIOnLine(sKey))
30        {
31            //正常登录需要的其它代码
32        }

33        else
34        {
35            //提示用户已登录的代码
36        }

37

38

    上边有很详细的注释,相信你会看的很明白。其实直接用这段代码一些,对于一些要求不是很高的客户。但是对于很挑剔的客户,你就会发现仅这样做还不够。
     待续。。。    
     最近比较忙,既然有人问了,我把源码贴出来吧。
     登录cs文件用到的部分代码:
 1public static bool AmIOnLine(string userName)
 2    {
 3        string sKey = userName;
 4        // 得到Cache中的给定Key的值
 5        string sUser = Convert.ToString(HttpContext.Current.Cache[sKey]);
 6        // 检查是否存在
 7        if (sUser == null || sUser == String.Empty)
 8        {
 9            // Cache中没有该Key的项目,表名用户没有登录,或者已经登录超时
10            // 注意下面使用的TimeSpan构造函数重载版本的方法,是进行是否登录判断的关键。
11            TimeSpan SessTimeOut = new TimeSpan(000600);
12            HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);
13            System.Web.HttpContext.Current.Session["User"= sKey;
14            // 首次登录,您可以做您想做的工作了。
15            return true;
16        }

17        else
18        {
19            // 在 Cache 中发现该用户的记录,已经登录过,禁止再次登录
20            return false;
21        }

22    }

23………………
24if (loginStatus == OA.Entity.LoginStatus.Success)
25                {
26                    // 生成Key
27                    string sKey = userName;
28                    // 得到Cache中的给定Key的值
29                    if (AmIOnLine(sKey))
30                    {
31                        //Session["User"] = userName;
32                        Response.Redirect("Manage/Index.aspx");
33                    }

34                    else
35                    {
36                        JScript.AlertAndRedirect("该帐号已经登录,不能重复登录!""Index.aspx");
37                    }

38                }

登录后页面aspx用到的代码:
 1<script language="javascript" type="text/javascript">
 2    document.onLoad = InformSSO();
 3    function InformSSO()
 4    {
 5        Default.CheckUsername();      
 6        setTimeout("InformSSO()",30000);
 7    }

 8    </script>
 9cs文件代码:
10 protected void Page_Load(object sender, EventArgs e)
11    {
12        AjaxPro.Utility.RegisterTypeForAjax(typeof(Manage_Index));//必要的
13    }

14    [AjaxPro.AjaxMethod]
15    public void CheckUsername()
16    {
17        if (Session["User"!= null)
18        {
19            TellServerIamALive();
20        }

21    }

22    public void TellServerIamALive()
23    {
24        string sKey = Session["User"].ToString();
25        // 得到Cache中的给定Key的值
26        string sUser = Convert.ToString(HttpContext.Current.Cache[sKey]);
27        // 检查是否存在
28        if (sUser == null || sUser == String.Empty)
29        {
30            TimeSpan SessTimeOut = new TimeSpan(000600);
31            HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);
32        }

33    }

34

这个功能需要用到AjaxPro.2.dll文件,在网上找吧,很多。先学会ajaxPro的配置和使用后看这段代码很容易的了。
posted @ 2008-01-10 17:50  juhnpen  阅读(1122)  评论(1编辑  收藏  举报