【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],在进行登录时进行判断,但是频繁的数据库操作,不是一个很好的解决方法,但是也是一种思路,可以尝试。如果下次收集到好的方法在来更新!
作者:ruicky
出处:http://www.cnblogs.com/ruicky/
欢迎任何形式的转载,未经作者同意,请保留此段声明!