防止用户多次登录
一、思路:
1、在sessionState为InProc时,每次新开一个IE窗口,都产生一个新的Session对象,每个Session的ID是唯一的(StateServer维持一个Session,不能利用SessionID);
2、以SessionID为键,登录的用户ID为键值,将用户的登录信息添加进键值对集合,然后保存到Application中;
3、每次登录时,在用户ID和密码验证成功后,检查登录的用户ID是否已存在于集合中,是则取出对应的键,在后面将该键的值置为空;
4、
二、具体实施:
1、在登录页进行处理:
Dictionary<string, string> dic = null; if (Application["LoginInfo"] != null) { string sessionId = "";//前面已经登录过的用户的SessionID值 //获取各个已登录用户的登录信息 dic = (Dictionary<string, string>)Application["LoginInfo"]; foreach (var item in dic) { //用户ID已存在,即用户已经登录 if (item.Value == userId) { //取出该条记录的key sessionId = item.Key; break; } } //当前登录的用户已经登录了,集合的值置为空 if (!string.IsNullOrEmpty(sessionId)) { dic[sessionId] = ""; } } else { dic = new Dictionary<string, string>(); } //在集合中为新登录用户存入唯一的SessionID和用户ID if (!dic.ContainsKey(Session.SessionID)) { dic.Add(Session.SessionID, userId); //存存储登录信息至Application Application.Lock(); Application["LoginInfo"] = dic; Application.UnLock(); }
2、新建一个页面基类,供各个页面继承,在里面添加OnInit()方法进行处理:
namespace outctrl { public class BasePage :System.Web.UI.Page { protected override void OnInit(EventArgs e) { if (Application["LoginInfo"] != null) { //获取已经存储的application值 Dictionary<string, string> dic = (Dictionary<string, string>)Application["LoginInfo"]; foreach (var item in dic) { //SessionID相同,是当前用户的信息 if (item.Key == Session.SessionID) { //值被置为空,表明用户已经在其他地方登录 if (string.IsNullOrEmpty(item.Value)) { dic.Remove(Session.SessionID); Application.Lock(); Application["LoginInfo"] = dic; Application.UnLock(); Response.Write("<script>alert('你的帐号已在别处登陆,你被强迫下线!');top.location.href = '../Login.aspx'</script>"); // Response.Redirect("Default.aspx"); Response.End(); } } } } } } }
3、设置一个退出页(或直接退出按钮),使用Session.Abandon(),以便结束当前Session对象,并调用Global文件的Session_End事件;
4、在Session_End事件里加入处理程序:
// 在会话结束时运行的代码。 // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer // 或 SQLServer,则不会引发该事件。 //获取已经存储的application值 if (Application["LoginInfo"] != null) { Dictionary<string, string> dic = (Dictionary<string, string>)Application["LoginInfo"]; if (dic.ContainsKey(Session.SessionID)) { //清除当前SessionID dic.Remove(Session.SessionID); Application.Lock(); Application["LoginInfo"] = dic; Application.UnLock(); } }