【ASP.NET】 实现 单点登录

【前言】 

最近,一个项目中要集成这个功能,就是一个账号只能同时一个人在线. 在网上搜索中,总是零零散散的。 今天写个系统点的,希望可以帮到大家!

【方法】

NO.1 Login.aspx 登录界面

    登录按钮:

    /// <summary>
    /// 登陆验证
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnLogin_Click(object sender, EventArgs e)
    {
        if (tbxPassword.Text.Trim() == "" || tbxUserName.Text.Trim() == "")
        {
            MsgBox("用户名或密码不能为空!");
            return;
        }
        string sql ="select * from t_user where username='"+tbxUserName.Text.Trim()+"' and state='1'";		
        DataTable dt = DbHelper.GetDataTable(sql);
        if (dt.rows.count <= 0)
        {
            MsgBox("用户不存在!");
            return;
        }
        else
        {
            string macAd = "";
            if (IsLoginState(user[0].Username, out macAd) || this.chkLogin.Checked) //IsLoginState是个方法在下个语句段中 chkLogined我设置的是强行登陆
            {
                if (user[0].Password == tbxPassword.Text.Trim())
                {
                    Session[Webconfig.UserCode] = user[0].Id;
                    Response.Redirect("Default.aspx");
                }
                else
                {
                    MsgBox("密码错误!");
                    return;
                }
            }
            string[] arrMac = macAd.Split('*');
            Response.Write(string.Format("<Script>alert('此账号已登录,IP地址({0}),mac地址({1})');history.go(-1);</script>", arrMac[1], arrMac[0]));
        }
    }
View Code
 1 string mac;//获得本机MAC地址
 2  
 3 private bool IsLoginState(string loginName, out string macAddress)
 4     {
 5         bool flag = true;
 6        // Cache.Insert("DSN", connectionString, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero); 
 7         string sUser = Convert.ToString(Cache[loginName]); // 检查是否存在 
 8         if (sUser == null || sUser == String.Empty)
 9         {
10             TimeSpan SessTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);//取得Session的过期时间 System.Web.HttpContext.Current.Session.Timeout
11             HttpContext.Current.Cache.Insert(loginName, loginName, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);//将值放入cache己方便单点登录 
12             string mac = getIPandMac();
13             HttpContext.Current.Cache.Insert(loginName + "_mac", mac + "*" + Request.UserHostAddress, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);
14             //成功登录 
15         }
16         else if (Cache[loginName].ToString() == loginName)//如果这个账号已经登录 
17         {
18             flag = false;
19         }
20         else
21         {
22             Session.Abandon();//这段主要是为了避免不必要的错误导致不能登录 
23         }
24         macAddress = Cache[loginName + "_mac"].ToString();
25         return flag;
26     }
27 
28     [DllImport("Iphlpapi.dll")]
29     private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
30     [DllImport("Ws2_32.dll")]
31     private static extern Int32 inet_addr(string ip);
32     private string getIPandMac()
33     {
34         string mac_dest = "";
35         try
36         {
37             string userip = Request.UserHostAddress;
38             string strClientIP = Request.UserHostAddress.ToString().Trim();
39             Int32 ldest = inet_addr(strClientIP); //目的地的ip 
40             Int32 lhost = inet_addr("");   //本地服务器的ip 
41             Int64 macinfo = new Int64();
42             Int32 len = 6;
43             int res = SendARP(ldest, 0, ref macinfo, ref len);
44             string mac_src = macinfo.ToString("X");
45             if (mac_src == "0")
46             {
47 
48             }
49             else
50             {
51                 while (mac_src.Length < 12)
52                 {
53                     mac_src = mac_src.Insert(0, "0");
54                 }
55                 for (int i = 0; i < 11; i++)
56                 {
57                     if (0 == (i % 2))
58                     {
59                         if (i == 10)
60                         {
61                             mac_dest = mac_dest.Insert(0, mac_src.Substring(i, 2));
62                         }
63                         else
64                         {
65                             mac_dest = "-" + mac_dest.Insert(0, mac_src.Substring(i, 2));
66                         }
67                     }
68                 }
69             }
70         }
71         catch (Exception err)
72         {
73             Response.Write(err.Message);
74         }
75         return mac_dest;
76     }

   PS:值得注意的是界面得引用一个命名空间:using System.Runtime.InteropServices;

NO.2  退出

   退出就是一个清楚缓存和session的过程

View Code
 1 protected void btnExit_Click(object sender, EventArgs e)
 2     {
 3         if (Session["user"]== null)
 4         {
 5             Response.Redirect("~/error/relogin.aspx");
 6         }
 7 
 8         if ( Session["user"]!= null)
 9         {
10             long id = Convert.ToInt64(Session["user"]);
11             string sql="select * from t_user where id='"+id+"'";
12             DataTable dt = DbHelper.GetDataTable(sql);
13             HttpContext.Current.Cache.Remove(dt.rows[0]["UserName"]);
14         }
15         Session.Clear();
16         Session.Remove(Session.SessionID);
17 
18         Response.Buffer = true;
19         Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1);
20         Response.Expires = 0;
21         Response.CacheControl = "no-cache";
22         Response.Clear();
23         Response.Redirect("~/Login.aspx");
24     }

【总结】

  这只是一个简单的单点登录(单一登陆)的方法,利用的缓存和Session的方法来进行控制。 我想法中还有一个方法就是在数据库中增加字段[State],在进行登录时进行判断,但是频繁的数据库操作,不是一个很好的解决方法,但是也是一种思路,可以尝试。如果下次收集到好的方法在来更新!

原文地址:https://www.cnblogs.com/ruicky/p/2680297.html