一直有个难题解决不了,一个用户已登录,该用户会话还存在的情况下,密码被他人改了,如何注销掉该用户的所有登录?

时间:2022-11-04 07:56:55
现在我是用session标记用户是否登录,现在假设用户A已登录,会话还存在,突然,管理员对A用户的密码进行修改,这时,用户A的登录应该是要被注销的,但是,我如何做到注销用户A的登录呢,也就是说如何做到清除已登录A的用户的session?

session的mode是inproc而不是sql

38 个解决方案

#1


路过UP 

#2


帮你顶下 我也想知道

#3


session是不能通知其他session的你必须用application来或者是放在数据库中才能够通知到其他的链接
所以你得让每一个链接都有自己的id,然后保存合法id为一个列表
在需要断指定链接的合法性时将指定链接的id从列表中删除就行了

#4


这个好象不能用session来做,应该用数据库来做吧.
设一个登陆字段,登陆了数据库里标为true,改密码的时候改为false这样来实现.

#5


注销session 这个用户的信息

#6


放数据库吧...弄个在线用户表,修改密码后删掉在线用户

#7


可以在每个页面里判断   如果密码改了,就K掉

#8


防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

#9


客户退出或断开时,清空session

#10


密码修改之后就把这个用户的session给clear或null掉就ok了

#11


估计是要在数据库字段中用个字段 来标识管理员是否修改了密码,然后程序中用8楼的AJAX 刷新页面

#12


实质问题,关注一下~

#13


密码修改完,强制从新登录.

在登录里进行判断用户是否已经登录.

在Application里缓存一个用户列表,采用 用户名和ip组合.

每次登录进行判断用户名在列表里存在不,存在就Remove掉,然后从新添加新的用户名和ip组合.

判断如何踢出用户我是加在了模版页里.

#14


session标识方法
在你的登陆session或者cookies中添加随机标识位,并且存入该用户数据库记录对应标识字段[需要新增],这样每次登陆都要生成新的标识session,更新数据库这个标识字段。 这样就可以做到用户登陆唯一性;
如果要实现你需要的功能,只需要在管理员更改用户密码的时候,清空或者更改数据库对应字段。
注:在每次操作中都增加用户登陆信息验证,包括用户名,密码,登陆标识位。

#15


引用 4 楼 uchiha2007 的回复:
这个好象不能用session来做,应该用数据库来做吧.
设一个登陆字段,登陆了数据库里标为true,改密码的时候改为false这样来实现.

问题是我不想将session用sql保存,因为那效率相对inproc稍差一些。

引用 5 楼 suyiming 的回复:
注销session 这个用户的信息

对啊,问题是他们都是不同的session,怎么请掉用户A的session呢?!

引用 7 楼 jl_lsj 的回复:
可以在每个页面里判断   如果密码改了,就K掉

这方法是可以,如果每次回发或加载页面都去数据库判断一次的话,那效率未免太差,还不如将session放在数据库来得好。

引用 10 楼 sunheartlee 的回复:
密码修改之后就把这个用户的session给clear或null掉就ok了


现在用户A登录了,管理员突然改掉他的密码,你怎么做到清掉用户A的session呢?!

引用 8 楼 kongwei521 的回复:
防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

就看,看完了来说体会。

#16


做一个basePage在那里面处理吧

#17


非要用session的放,可以使用Sql2005里面的SqlDependency

不过偶一般都是用sql表来保存在线状态的

#18


引用 17 楼 bindsang 的回复:
非要用session的放,可以使用Sql2005里面的SqlDependency

不过偶一般都是用sql表来保存在线状态的

但很明显用SQL保存SESSION状态没有比放在进程中效率稍差一点。

#19


我估计楼主的努力会白费,Session是寄存在服务器内存中的数据,他们是根据SessionID来读取的,
管理员在改变密码的时候,服务器根本就不知道,这个用户对应的SessionID是什么,又怎么去清除了呢?
你该不会修改一个人的密码,清楚了服务器上所有的Session值吧!

建议:
你可以自己做个Session对象,把信息放在一个Hashtable表中,
那样,你就可以根据,用户的名称来清除他在Hashtable中的值了

#20


引用 2 楼 suyuan19 的回复:
帮你顶下 我也想知道

#21


我也想知道

#22



最好做个在线表,
如果某在线用户密码被修改,则在线表的Flag状态改变

当系统检测到Flag改变的时候,强制此用户重新登录


#23


用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session

#24


引用 18 楼 WDandan 的回复:
引用 17 楼 bindsang 的回复:
非要用session的放,可以使用Sql2005里面的SqlDependency 

不过偶一般都是用sql表来保存在线状态的 
 
但很明显用SQL保存SESSION状态没有比放在进程中效率稍差一点。


对于需要用到负载平衡的站点来说,进程内的session是没有办法在多台服务间进行同步的,或者说有这样的方法,但效率太低了
偶一般做的站点都是用的负载平衡的站的

#25


引用 22 楼 Catmaoo 的回复:
最好做个在线表, 
如果某在线用户密码被修改,则在线表的Flag状态改变 

当系统检测到Flag改变的时候,强制此用户重新登录 

这个和用数据库存Session一样的,而且何必要Flag状态呢,直接删除不是更好,还少了一些无用数据

#26


用Application也好,静态字段也好,数据库也行,序列化的结构类型也可以,找一个全域似能记录变量的东西把要踢出去的会员编号作成个列表记下来,
每次刷新时核对当前会员的编号是不是在这列表里,如果在就out,不在就就请继续

完毕

#27


呃,错别字“全域似”是“全域式”即是指凡是访问这个站的用户都能读到的地方

#28


引用 23 楼 seesea125 的回复:
用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session

#29


略。

 

思路:

记录用户登陆信息[登陆时间,用户ID]

每隔一段时间(如5秒怎么样?)检查存储的登陆信息。如果发现多个,则比较各个的登陆时间,如果自己用的登陆时间比其他的早,则提示并注销。

 

实现:

1.把所有登陆用户存在这个全局Application中(建议把这个Application放在基类,方便调用):

protected IList<IList> LoginInfo

        {

            get 

            {

                if (Application["loginInfo"] == null)

                {

                    Application["loginInfo"] = new List<IList>();

                }

                return (IList<IList>)Application["loginInfo"];

            }

        }

 

 

 

 

用户成功登陆时,保存登陆的用户名与登陆时间:

DateTime dt = DateTime.Now;

//这里保存当前用户的登陆状态,保存登陆信息

 

Session[“UserInfo”] = user.GetUserInfoByUName(userName, ref error);

Session[“LastLoginDate”].LastLoginDate = dt;

 

//这里把该用户名与登陆时间存到登陆用户列表中:

IList al = new ArrayList();

al.Add(txtUserName.Text);

al.Add(dt);

LoginInfo.Add(al);

 

 

页面里增加脚本,每隔一段时间(5秒)取一下状态,看看这个用户名是不是在其他地方登陆了,这里用到了prototype的ajax:

<script language='javascript' type='text/javascript'>"

function ValidSimpleUser()

{

new Ajax.Request('LeadNT.aspx?op=otherLogin', 

{onSuccess: function(transport) 

{

if(transport.responseText == 1')

top.location.href=''LeadNT.aspx?op=logout';}

}); 

}

setInterval('ValidSimpleUser();',5000);

</script>

 

 

脚本中用到了一个页面LeadNT.aspx,第一次调用返回一个值,如果是1 ,则表示别人登陆这个帐号了,第二次调用,是用这个页面来注销当前用户:

 

LeadNT.aspx中的部分代码:

 

//第一次调用:

if (Request.QueryString["op"] == "otherLogin")

            {

                if (!string.IsNullOrEmpty(CUser.UserName))

                {

                    foreach (IList li in LoginInfo)

                    {

                        if (li[0].ToString() == CUser.UserName && DateTime.Parse(li[1].ToString()) > CUser.LastLoginDate)

                        {

                            LoginInfo.Remove(li);

                            Response.Write("1");

                            break;

                            return;

                        }

                    }

                }

            }

 

            //第二次调用

            if (Request.QueryString["op"] == "logout")

            {

 Response.Write("<script language='javascript' type='text/javascript'>alert('该帐号已在其他地方登录!');top.location.href=' "Logon.aspx?logout=true';</script>");

            }

 

这里调用logon.aspx是注销当前用户。

 

这样就实现了单用户登陆功能。当一个帐号同时登陆2次时,第一次会被刷下。

 

总结:

 

本文详细介绍了如何防止用一用户同时登陆。

作者:roydux

出处:http://www.LeadNT.Org
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



感觉上面的方法对服务器的压力是不是太大了。









\

#30


用AJAX来做,强制跳转页面重新登陆.

#31


感谢大家的关注。


引用 8 楼 kongwei521 的回复:
防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

我看了,但存在一个非常致命的问题,考虑过没有,如果一个用户没有正常注销登录,如直接关了浏览器,而不是点我们给定的注销命令,那么,系统就永远也不知道该用户已注销,在application里的list的项目(item)不会被清除,永远在内存里。
我想过在session_onend事件里清除,但当session_onend时,我们无论如何也获取不到之前该会话的用户是什么呀!!!


引用 19 楼 ufostop 的回复:
我估计楼主的努力会白费,Session是寄存在服务器内存中的数据,他们是根据SessionID来读取的,
管理员在改变密码的时候,服务器根本就不知道,这个用户对应的SessionID是什么,又怎么去清除了呢?
你该不会修改一个人的密码,清楚了服务器上所有的Session值吧!

建议:
你可以自己做个Session对象,把信息放在一个Hashtable表中,
那样,你就可以根据,用户的名称来清除他在Hashtable中的值了


这个问题与上面一样,不用session这种会自动清除的对象,我们无法保证及时清除对象。


引用 22 楼 Catmaoo 的回复:
最好做个在线表,
如果某在线用户密码被修改,则在线表的Flag状态改变

当系统检测到Flag改变的时候,强制此用户重新登录


还是跟上面一样,无法保证及时清除对象。



引用 26 楼 oyiboy 的回复:
用Application也好,静态字段也好,数据库也行,序列化的结构类型也可以,找一个全域似能记录变量的东西把要踢出去的会员编号作成个列表记下来,
每次刷新时核对当前会员的编号是不是在这列表里,如果在就out,不在就就请继续

完毕



还是跟上面的问题一样呀!!!

引用 23 楼 seesea125 的回复:
用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session


象定时器这样的东西应用到这里,就跟8楼推荐里的文章一样,不好,我们要做到的是回发或加载页面时判断就行,这样既不会做多余的运算,也不会因为延时而有漏网之鱼。

#32


最简单的办法 ,修改密码就,清空session

#33


引用 32 楼 cndrip 的回复:
最简单的办法 ,修改密码就,清空session


清空整站SESSION?!朋友,不要开玩笑了,这明显是不可行的。

#34


这样似乎没法注销用户的session

#35


貌似session有过期时间的啊

#36


引用 33 楼 WDandan 的回复:
引用 32 楼 cndrip 的回复:
最简单的办法 ,修改密码就,清空session 
 

#37


引用 2 楼 suyuan19 的回复:
帮你顶下 我也想知道

#38


lz要实现得效果只用session是肯定不得行得

建议数据库建一个在线表,修改密码后删掉修改用户

前台页面只有定时与数据库比较,如果存在就清空session重新登陆


还有其他好的方法我也想了解一下

#1


路过UP 

#2


帮你顶下 我也想知道

#3


session是不能通知其他session的你必须用application来或者是放在数据库中才能够通知到其他的链接
所以你得让每一个链接都有自己的id,然后保存合法id为一个列表
在需要断指定链接的合法性时将指定链接的id从列表中删除就行了

#4


这个好象不能用session来做,应该用数据库来做吧.
设一个登陆字段,登陆了数据库里标为true,改密码的时候改为false这样来实现.

#5


注销session 这个用户的信息

#6


放数据库吧...弄个在线用户表,修改密码后删掉在线用户

#7


可以在每个页面里判断   如果密码改了,就K掉

#8


防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

#9


客户退出或断开时,清空session

#10


密码修改之后就把这个用户的session给clear或null掉就ok了

#11


估计是要在数据库字段中用个字段 来标识管理员是否修改了密码,然后程序中用8楼的AJAX 刷新页面

#12


实质问题,关注一下~

#13


密码修改完,强制从新登录.

在登录里进行判断用户是否已经登录.

在Application里缓存一个用户列表,采用 用户名和ip组合.

每次登录进行判断用户名在列表里存在不,存在就Remove掉,然后从新添加新的用户名和ip组合.

判断如何踢出用户我是加在了模版页里.

#14


session标识方法
在你的登陆session或者cookies中添加随机标识位,并且存入该用户数据库记录对应标识字段[需要新增],这样每次登陆都要生成新的标识session,更新数据库这个标识字段。 这样就可以做到用户登陆唯一性;
如果要实现你需要的功能,只需要在管理员更改用户密码的时候,清空或者更改数据库对应字段。
注:在每次操作中都增加用户登陆信息验证,包括用户名,密码,登陆标识位。

#15


引用 4 楼 uchiha2007 的回复:
这个好象不能用session来做,应该用数据库来做吧.
设一个登陆字段,登陆了数据库里标为true,改密码的时候改为false这样来实现.

问题是我不想将session用sql保存,因为那效率相对inproc稍差一些。

引用 5 楼 suyiming 的回复:
注销session 这个用户的信息

对啊,问题是他们都是不同的session,怎么请掉用户A的session呢?!

引用 7 楼 jl_lsj 的回复:
可以在每个页面里判断   如果密码改了,就K掉

这方法是可以,如果每次回发或加载页面都去数据库判断一次的话,那效率未免太差,还不如将session放在数据库来得好。

引用 10 楼 sunheartlee 的回复:
密码修改之后就把这个用户的session给clear或null掉就ok了


现在用户A登录了,管理员突然改掉他的密码,你怎么做到清掉用户A的session呢?!

引用 8 楼 kongwei521 的回复:
防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

就看,看完了来说体会。

#16


做一个basePage在那里面处理吧

#17


非要用session的放,可以使用Sql2005里面的SqlDependency

不过偶一般都是用sql表来保存在线状态的

#18


引用 17 楼 bindsang 的回复:
非要用session的放,可以使用Sql2005里面的SqlDependency

不过偶一般都是用sql表来保存在线状态的

但很明显用SQL保存SESSION状态没有比放在进程中效率稍差一点。

#19


我估计楼主的努力会白费,Session是寄存在服务器内存中的数据,他们是根据SessionID来读取的,
管理员在改变密码的时候,服务器根本就不知道,这个用户对应的SessionID是什么,又怎么去清除了呢?
你该不会修改一个人的密码,清楚了服务器上所有的Session值吧!

建议:
你可以自己做个Session对象,把信息放在一个Hashtable表中,
那样,你就可以根据,用户的名称来清除他在Hashtable中的值了

#20


引用 2 楼 suyuan19 的回复:
帮你顶下 我也想知道

#21


我也想知道

#22



最好做个在线表,
如果某在线用户密码被修改,则在线表的Flag状态改变

当系统检测到Flag改变的时候,强制此用户重新登录


#23


用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session

#24


引用 18 楼 WDandan 的回复:
引用 17 楼 bindsang 的回复:
非要用session的放,可以使用Sql2005里面的SqlDependency 

不过偶一般都是用sql表来保存在线状态的 
 
但很明显用SQL保存SESSION状态没有比放在进程中效率稍差一点。


对于需要用到负载平衡的站点来说,进程内的session是没有办法在多台服务间进行同步的,或者说有这样的方法,但效率太低了
偶一般做的站点都是用的负载平衡的站的

#25


引用 22 楼 Catmaoo 的回复:
最好做个在线表, 
如果某在线用户密码被修改,则在线表的Flag状态改变 

当系统检测到Flag改变的时候,强制此用户重新登录 

这个和用数据库存Session一样的,而且何必要Flag状态呢,直接删除不是更好,还少了一些无用数据

#26


用Application也好,静态字段也好,数据库也行,序列化的结构类型也可以,找一个全域似能记录变量的东西把要踢出去的会员编号作成个列表记下来,
每次刷新时核对当前会员的编号是不是在这列表里,如果在就out,不在就就请继续

完毕

#27


呃,错别字“全域似”是“全域式”即是指凡是访问这个站的用户都能读到的地方

#28


引用 23 楼 seesea125 的回复:
用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session

#29


略。

 

思路:

记录用户登陆信息[登陆时间,用户ID]

每隔一段时间(如5秒怎么样?)检查存储的登陆信息。如果发现多个,则比较各个的登陆时间,如果自己用的登陆时间比其他的早,则提示并注销。

 

实现:

1.把所有登陆用户存在这个全局Application中(建议把这个Application放在基类,方便调用):

protected IList<IList> LoginInfo

        {

            get 

            {

                if (Application["loginInfo"] == null)

                {

                    Application["loginInfo"] = new List<IList>();

                }

                return (IList<IList>)Application["loginInfo"];

            }

        }

 

 

 

 

用户成功登陆时,保存登陆的用户名与登陆时间:

DateTime dt = DateTime.Now;

//这里保存当前用户的登陆状态,保存登陆信息

 

Session[“UserInfo”] = user.GetUserInfoByUName(userName, ref error);

Session[“LastLoginDate”].LastLoginDate = dt;

 

//这里把该用户名与登陆时间存到登陆用户列表中:

IList al = new ArrayList();

al.Add(txtUserName.Text);

al.Add(dt);

LoginInfo.Add(al);

 

 

页面里增加脚本,每隔一段时间(5秒)取一下状态,看看这个用户名是不是在其他地方登陆了,这里用到了prototype的ajax:

<script language='javascript' type='text/javascript'>"

function ValidSimpleUser()

{

new Ajax.Request('LeadNT.aspx?op=otherLogin', 

{onSuccess: function(transport) 

{

if(transport.responseText == 1')

top.location.href=''LeadNT.aspx?op=logout';}

}); 

}

setInterval('ValidSimpleUser();',5000);

</script>

 

 

脚本中用到了一个页面LeadNT.aspx,第一次调用返回一个值,如果是1 ,则表示别人登陆这个帐号了,第二次调用,是用这个页面来注销当前用户:

 

LeadNT.aspx中的部分代码:

 

//第一次调用:

if (Request.QueryString["op"] == "otherLogin")

            {

                if (!string.IsNullOrEmpty(CUser.UserName))

                {

                    foreach (IList li in LoginInfo)

                    {

                        if (li[0].ToString() == CUser.UserName && DateTime.Parse(li[1].ToString()) > CUser.LastLoginDate)

                        {

                            LoginInfo.Remove(li);

                            Response.Write("1");

                            break;

                            return;

                        }

                    }

                }

            }

 

            //第二次调用

            if (Request.QueryString["op"] == "logout")

            {

 Response.Write("<script language='javascript' type='text/javascript'>alert('该帐号已在其他地方登录!');top.location.href=' "Logon.aspx?logout=true';</script>");

            }

 

这里调用logon.aspx是注销当前用户。

 

这样就实现了单用户登陆功能。当一个帐号同时登陆2次时,第一次会被刷下。

 

总结:

 

本文详细介绍了如何防止用一用户同时登陆。

作者:roydux

出处:http://www.LeadNT.Org
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



感觉上面的方法对服务器的压力是不是太大了。









\

#30


用AJAX来做,强制跳转页面重新登陆.

#31


感谢大家的关注。


引用 8 楼 kongwei521 的回复:
防止同一用户同时登陆的实现http://www.leadnt.org/post/246.html别人的文章你看看吧

我看了,但存在一个非常致命的问题,考虑过没有,如果一个用户没有正常注销登录,如直接关了浏览器,而不是点我们给定的注销命令,那么,系统就永远也不知道该用户已注销,在application里的list的项目(item)不会被清除,永远在内存里。
我想过在session_onend事件里清除,但当session_onend时,我们无论如何也获取不到之前该会话的用户是什么呀!!!


引用 19 楼 ufostop 的回复:
我估计楼主的努力会白费,Session是寄存在服务器内存中的数据,他们是根据SessionID来读取的,
管理员在改变密码的时候,服务器根本就不知道,这个用户对应的SessionID是什么,又怎么去清除了呢?
你该不会修改一个人的密码,清楚了服务器上所有的Session值吧!

建议:
你可以自己做个Session对象,把信息放在一个Hashtable表中,
那样,你就可以根据,用户的名称来清除他在Hashtable中的值了


这个问题与上面一样,不用session这种会自动清除的对象,我们无法保证及时清除对象。


引用 22 楼 Catmaoo 的回复:
最好做个在线表,
如果某在线用户密码被修改,则在线表的Flag状态改变

当系统检测到Flag改变的时候,强制此用户重新登录


还是跟上面一样,无法保证及时清除对象。



引用 26 楼 oyiboy 的回复:
用Application也好,静态字段也好,数据库也行,序列化的结构类型也可以,找一个全域似能记录变量的东西把要踢出去的会员编号作成个列表记下来,
每次刷新时核对当前会员的编号是不是在这列表里,如果在就out,不在就就请继续

完毕



还是跟上面的问题一样呀!!!

引用 23 楼 seesea125 的回复:
用个定时器,定时查看数据库这个用户表,在线用户密码被修改和session的不一样时,清空session


象定时器这样的东西应用到这里,就跟8楼推荐里的文章一样,不好,我们要做到的是回发或加载页面时判断就行,这样既不会做多余的运算,也不会因为延时而有漏网之鱼。

#32


最简单的办法 ,修改密码就,清空session

#33


引用 32 楼 cndrip 的回复:
最简单的办法 ,修改密码就,清空session


清空整站SESSION?!朋友,不要开玩笑了,这明显是不可行的。

#34


这样似乎没法注销用户的session

#35


貌似session有过期时间的啊

#36


引用 33 楼 WDandan 的回复:
引用 32 楼 cndrip 的回复:
最简单的办法 ,修改密码就,清空session 
 

#37


引用 2 楼 suyuan19 的回复:
帮你顶下 我也想知道

#38


lz要实现得效果只用session是肯定不得行得

建议数据库建一个在线表,修改密码后删掉修改用户

前台页面只有定时与数据库比较,如果存在就清空session重新登陆


还有其他好的方法我也想了解一下