zoukankan      html  css  js  c++  java
  • Asp.net中实现同一用户名不能同时登录(单点登录)

    Web 项目中经常遇到的问题就是同一用户名多次登录的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:

    将登录后的用户名放到数据库表中;

    登录后的用户名放到Session中;

    登录后的用户名放到Application中;

    登录后的用户名放到Cache中。

        一般的这几种方法都是登录了之后,如果没有正常退出,第二次登录将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登录的时候,因为Session没有过期等问题,会被拒绝继续登录系统,只能等待Session过期后才能登录。本文介绍的方法是采用类似于MSN登陆的方法,第二次登录时会把第一次的登录注销掉,第一次登录将会类似于MSN弹出:您的帐号已在别处被登录,您被强迫下线的提示信息。
    功能实现起来也比较简单: 
    登录用户名密码验证通过之后输入以下代码: 

    复制代码
    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] = "XXXXXX";  
    break;  
    }  
    }  
    }  
    else  
    {  
    hOnline = new Hashtable();  
    }  
    hOnline[Session.SessionID] = UserID;  
    Application.Lock();  
    Application["Online"] = hOnline;  
    Application.UnLock();
    复制代码

    用户登录的时候将登录用户名放在一个全局变量Online,Online为Hashtable结构,Key为SessionID,Value为用户名。每次用户登录时均判断以下要登录的用户名在Online中是不是已经存在,如果存在该用户名已经被登录,将第一个人登录的SessionID对应的用户名强制变更为XXXXXX,表示该登录将被强制注销。
    建立一个CommonPage页,系统中所有的页面都继承于CommonPage页,在CommonPage页的后台代码中添加如下代码:

    复制代码
    override protected void OnInit(EventArgs e) 
    {  
    Hashtable hOnline = (Hashtable)Application["Online"]; 
    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 && "XXXXXX".Equals(idE.Value.ToString())) 
    {  
    hOnline.Remove(Session.SessionID);  
    Application.Lock();  
    Application["Online"] = hOnline;  
    Application.UnLock();  
    MessageBox("你的帐号已在别处登录,您被强迫下线!",Login.aspx); 
    return false;  
    }  
    break;  
    }  
    }  
    }  
    }
    复制代码

    继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。
    最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:

    复制代码
    Hashtable hOnline = (Hashtable)Application["Online"]; 
    if(hOnline[Session.SessionID] != null) 
    {  
    hOnline.Remove(Session.SessionID);  
    Application.Lock();  
    Application["Online"] = hOnline;  
    Application.UnLock();  
    }
    复制代码
    如果用户不正常退出后重登录,因为重登录的优先级大,不会影响用户的登录,而不正常退出的用户占用的资源会在Session过期后自动清除,不会影响系统的性能。 
    为保证WEB系统安全,需要具有单点登录检测功能,Google了一下做了小小修改。 
    1)密码验证后:
    复制代码
    Hashtable hOnline = (Hashtable)Application["Online"];  
                      if (hOnline != null)  
                      {  
                       int i = 0;  
                        while (i<hOnline.Count) //因小BUG所以增加此判断,强制查询到底 
                          {  
                          IDictionaryEnumerator idE = hOnline.GetEnumerator();  
                          string strKey = "";  
                          while (idE.MoveNext())  
                          {  
                              if (idE.Value != null && idE.Value.ToString().Equals(this.username.Text)) 
                              {  
                                  //already login              
                                  strKey = idE.Key.ToString();  
                                  hOnline[strKey] = "XXXXXX";  
                                  break;  
                              }  
                          }  
                          i = i + 1; 
                          }  
                      }  
                      else  
                      {  
                          hOnline = new Hashtable();  
                      }  
                      hOnline[Session.SessionID] = this.username.Text;  
                      Application.Lock();  
                      Application["Online"] = hOnline;  
                      Application.UnLock();  
                      //用户登录的时候将登录用户名放在一个全局变量Online,Online为Hashtable结构,  
                      //Key为SessionID,Value为用户名。每次用户登录时均判断以下要登录的用户名在Online中是不是已经存在, 
                      //如果存在该用户名已经被登录,将第一个人登录的SessionID对应的用户名强制变更为XXXXXX,表示该登录将被强制注销
    复制代码

    2)建立一个CommonPage页,系统中所有的页面都继承于CommonPage页(public partial class index : CommonPage),在CommonPage页的后台代码中添加如下代码:

    复制代码
    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;  
    using System.Collections; 
    /// <summary>  
    /// CommonPage 防止用户多点登录  
    /// </summary>  
    public class CommonPage: System.Web.UI.Page  
    {  
         public CommonPage()  
    {  
       //  
       // TODO: 在此处添加构造函数逻辑  
       //  
    }  
       override protected void OnInit(EventArgs e)  
         {  
             Hashtable hOnline = (Hashtable)Application["Online"];  
             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 && "XXXXXX".Equals(idE.Value.ToString())) 
                         {  
                             hOnline.Remove(Session.SessionID);  
                             Application.Lock();  
                             Application["Online"] = hOnline;  
                             Application.UnLock();  
                            string js = "<script language=javascript>alert('{0}');window.location.replace('{1}')</script>"; 
                             Response.Write(string.Format(js, "帐号已在别处登录 ,你将被强迫下线(请保管好自己的用户密码)!", "logout.aspx?cname=noadmin")); 
       
                             return;  
                         }  
                         break;  
                     }  
                 }  
             }  
         }  
    }
    复制代码

    继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。
    3)最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:

    复制代码
    Hashtable hOnline = (Hashtable)Application["Online"];  
       if(hOnline[Session.SessionID] != null)  
       {  
         hOnline.Remove(Session.SessionID);  
         Application.Lock();  
         Application["Online"] = hOnline;  
         Application.UnLock();  
       }
    复制代码
     
  • 相关阅读:
    [LeetCode] 1019. Next Greater Node In Linked List 链表中的下一个较大的结点
    [LeetCode] 1018. Binary Prefix Divisible By 5 可被5整除的二进制前缀
    [LeetCode] 1017. Convert to Base -2 负二进制转换
    [LeetCode] 1016. Binary String With Substrings Representing 1 To N 子串能表示从1到N数字的二进制串
    [LeetCode] 1015. Smallest Integer Divisible by K 可以整除K的最小整数
    [LeetCode] 1014. Best Sightseeing Pair 最佳观光组合
    [LeetCode] 1013. Partition Array Into Three Parts With Equal Sum 将数组分成和相等的三个部分
    [LeetCode] 1012. Numbers With Repeated Digits 至少有1位重复的数字
    [LeetCode] 1011. Capacity To Ship Packages Within D Days 在D天内送达包裹的能力
    [LeetCode] 1010. Pairs of Songs With Total Durations Divisible by 60 总持续时间可被60整除的歌曲
  • 原文地址:https://www.cnblogs.com/webenh/p/6051340.html
Copyright © 2011-2022 走看看