• 防止用户多次登录


    一、思路:

    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();
                    }
                }
  • 相关阅读:
    关于ARMv8另外几个问题
    C++中的内存区域及其性能特征
    外点惩处函数法·约束优化问题
    【LaTeX排版】LaTeX论文模版
    fatal error: vector: No such file or directory
    【UNIX网络编程(三)】TCP客户/server程序演示样例
    LOJ#6437. 「PKUSC2018」PKUSC
    mybatis 学习一 建立maven项目
    maven学习5 构建MyBatis项目
    maven学习4 使用Maven构建Spring项目
  • 原文地址:https://www.cnblogs.com/qfcndtt/p/2870107.html
Copyright © 2020-2023  润新知