asp.net用户名不允许重复登录!
目前我的方案是:
1:数据库设计,登录表加一个字段LoginStatus(登录状态),0表示未登录,1已经登录
2:登录逻辑,在登录时检查该字段,为0才可以登录
3:用户退出
点击退出:在注销页面设置登录状态为0;
自动退出:在Session_End事件中设置状态为0;
4:处理特殊情况:
用户直接关闭了页面,无法再次进入。我在登录页面的Page_Load里判断会话,如果不为空则直接跳转到工作页面;
但问题是,如果服务器出现异常情况,导致状态没有实现复位,那就麻烦了!!!!
请教大家,此问题有什么解决方案,或是对于不允许重复登录功能有没有其它的替代方案
---谢谢!!!!
...全文
请发表友善的回复…
发表回复
yuxh81 2010-10-20
- 打赏
- 举报
谢谢各位的回答!
采用了23#的方案,即
使用服务器Application对象来存储用户登录状态默契
+
QQ的不允许重复思想(新登录的直接挤掉旧的)
简单总结一下:
对于存储方式,基本分为两种:A-数据库 B-服务器内存(Application、Cache);
数据库方式的数据会很稳定,但需要做一些额外的事情,如:服务器出现异常导致重启,则需要执行状态复位操作,但个人觉得在这个应用里,稳定不是关键,也就是该不该被持久化的问题!!
对于业务逻辑,则有两种,
A:我采用的QQ方式是其中之一,这一种最好的方面就是不用担心用户直接关闭了浏览器而无法再次登录;坏处是,在前面用户毫无察觉的情况下使其下线,不友好(不知道各位是否赞同?);
B:再就是常规的,若已有用户登录,则后者无法再次登录,这一种需要根据用户的会话状态来动态更改其登录状态,比如:登录后就改为已登录(当然,需要检查是否已经登录),退出(会话超时自动退出,点击安全退出)后改为未登录,这一种的难度就在于:用户一旦直接关闭浏览器则在会话有效期内无法再次登录(当然我相信有一些方法来弥补这一点,但个人觉得不完美!)
注:以上只是我个人的理解,只供参考,若存在问题,请指出!!谢谢!!
采用了23#的方案,即
使用服务器Application对象来存储用户登录状态默契
+
QQ的不允许重复思想(新登录的直接挤掉旧的)
简单总结一下:
对于存储方式,基本分为两种:A-数据库 B-服务器内存(Application、Cache);
数据库方式的数据会很稳定,但需要做一些额外的事情,如:服务器出现异常导致重启,则需要执行状态复位操作,但个人觉得在这个应用里,稳定不是关键,也就是该不该被持久化的问题!!
对于业务逻辑,则有两种,
A:我采用的QQ方式是其中之一,这一种最好的方面就是不用担心用户直接关闭了浏览器而无法再次登录;坏处是,在前面用户毫无察觉的情况下使其下线,不友好(不知道各位是否赞同?);
B:再就是常规的,若已有用户登录,则后者无法再次登录,这一种需要根据用户的会话状态来动态更改其登录状态,比如:登录后就改为已登录(当然,需要检查是否已经登录),退出(会话超时自动退出,点击安全退出)后改为未登录,这一种的难度就在于:用户一旦直接关闭浏览器则在会话有效期内无法再次登录(当然我相信有一些方法来弥补这一点,但个人觉得不完美!)
注:以上只是我个人的理解,只供参考,若存在问题,请指出!!谢谢!!
AsheBin 2010-10-19
- 打赏
- 举报
可以持久化,但是没必要持久化。
放在服务器缓存中就可以。再次登录的时候判断当前用户列表中有没有,有的话,说明已经登录。
放在服务器缓存中就可以。再次登录的时候判断当前用户列表中有没有,有的话,说明已经登录。
yuxh81 2010-10-19
- 打赏
- 举报
[Quote=引用 14 楼 jarry42 的回复:]
我说一个比较普遍的做法,我看过很多就是这么干的
其实可以这样的,用一个Application存储一个Table
Table里记录username,sessionid,time
那么在正式登陆之前就检查这个Table就可以了
用户退出,可以根据这个Table移除记录,session timeout可以根据sessionid移除记录
服务器中断了 Application也就没了..……
[/Quote]
我也在想,对于用户状态到底需不需要被持久化(入数据库)!!以及持久化有什么好处没!
我说一个比较普遍的做法,我看过很多就是这么干的
其实可以这样的,用一个Application存储一个Table
Table里记录username,sessionid,time
那么在正式登陆之前就检查这个Table就可以了
用户退出,可以根据这个Table移除记录,session timeout可以根据sessionid移除记录
服务器中断了 Application也就没了..……
[/Quote]
我也在想,对于用户状态到底需不需要被持久化(入数据库)!!以及持久化有什么好处没!
yuxh81 2010-10-19
- 打赏
- 举报
[Quote=引用 16 楼 kywlw 的回复:]
楼主这种做法,类似于ASP的“江湖”登陆判定。
还有另外一种思路,就是在Session上做手脚,我手头上的一个项目是采用重写Session实现的(直接模拟了Session的原理,在登陆时使用自己写的Session而不使用微软的官方Session)。
使用自己写Session的方式,当服务器遇上不可预测的重大问题时,将导致应用程序池进行重启,那么Session将会自动复位。在判定的时候……
[/Quote]
感觉这个方案过于复杂了!!
楼主这种做法,类似于ASP的“江湖”登陆判定。
还有另外一种思路,就是在Session上做手脚,我手头上的一个项目是采用重写Session实现的(直接模拟了Session的原理,在登陆时使用自己写的Session而不使用微软的官方Session)。
使用自己写Session的方式,当服务器遇上不可预测的重大问题时,将导致应用程序池进行重启,那么Session将会自动复位。在判定的时候……
[/Quote]
感觉这个方案过于复杂了!!
kywlw 2010-10-19
- 打赏
- 举报
楼主这种做法,类似于ASP的“江湖”登陆判定。
还有另外一种思路,就是在Session上做手脚,我手头上的一个项目是采用重写Session实现的(直接模拟了Session的原理,在登陆时使用自己写的Session而不使用微软的官方Session)。
使用自己写Session的方式,当服务器遇上不可预测的重大问题时,将导致应用程序池进行重启,那么Session将会自动复位。在判定的时候也变的非常简单,直接把自己写的Session当做登陆清单对照就行了。
还有另外一种思路,就是在Session上做手脚,我手头上的一个项目是采用重写Session实现的(直接模拟了Session的原理,在登陆时使用自己写的Session而不使用微软的官方Session)。
使用自己写Session的方式,当服务器遇上不可预测的重大问题时,将导致应用程序池进行重启,那么Session将会自动复位。在判定的时候也变的非常简单,直接把自己写的Session当做登陆清单对照就行了。
农夫it 2010-10-19
- 打赏
- 举报
对 1 2 3 楼很无语...
农夫it 2010-10-19
- 打赏
- 举报
我说一个比较普遍的做法,我看过很多就是这么干的
其实可以这样的,用一个Application存储一个Table
Table里记录username,sessionid,time
那么在正式登陆之前就检查这个Table就可以了
用户退出,可以根据这个Table移除记录,session timeout可以根据sessionid移除记录
服务器中断了 Application也就没了...这个思路应该可以帮你解决
其实可以这样的,用一个Application存储一个Table
Table里记录username,sessionid,time
那么在正式登陆之前就检查这个Table就可以了
用户退出,可以根据这个Table移除记录,session timeout可以根据sessionid移除记录
服务器中断了 Application也就没了...这个思路应该可以帮你解决
myhope88 2010-10-19
- 打赏
- 举报
网上搜一下很多的,这个问题已经被讨论了很久了
yuxh81 2010-10-19
- 打赏
- 举报
贴子已加分,等级有限,只能200分!
yuxh81 2010-10-19
- 打赏
- 举报
但问题是,如果服务器出现异常情况,导致状态没有实现复位,那就麻烦了!!!!
现有一种方法可以解决此问题,即:用户可以选择强迫对方下线!
但这样做,感觉不是很好!!!
现有一种方法可以解决此问题,即:用户可以选择强迫对方下线!
但这样做,感觉不是很好!!!
Rock870210 2010-10-19
- 打赏
- 举报
额。。。学习
vip__888 2010-10-19
- 打赏
- 举报
google 防止同时登陆。
yuxh81 2010-10-19
- 打赏
- 举报
请大家注意顶楼,红色字!!
我相信,关于用户直接关闭页面的问题我已经通过顶楼的第 3 点解决了!!!!
我相信,关于用户直接关闭页面的问题我已经通过顶楼的第 3 点解决了!!!!
yuxh81 2010-10-19
- 打赏
- 举报
[Quote=引用 4 楼 moudy 的回复:]
1.设置超时时间,如最后在线时间点超过10分钟再登陆即使状态为已登陆也允许再登陆,这要求在已登陆用户设置类似心跳包,隔多久在数据库中记录用户的最后在线时间点。
2.服务器异常,重启后想办法初始化该表所有状态为未登录(sqlSERVER可以用JOB实现)
[/Quote]
第1点不太懂,web.config文件中的<sessionState mode="InProc" cookieless="false" timeout="10"/>
配合Global.asax文件中的Session_End事件不能达到这一效果吗?
第2点,明白,但不知道这个好不好弄(主要是我没弄过sqlServer的作业)
1.设置超时时间,如最后在线时间点超过10分钟再登陆即使状态为已登陆也允许再登陆,这要求在已登陆用户设置类似心跳包,隔多久在数据库中记录用户的最后在线时间点。
2.服务器异常,重启后想办法初始化该表所有状态为未登录(sqlSERVER可以用JOB实现)
[/Quote]
第1点不太懂,web.config文件中的<sessionState mode="InProc" cookieless="false" timeout="10"/>
配合Global.asax文件中的Session_End事件不能达到这一效果吗?
第2点,明白,但不知道这个好不好弄(主要是我没弄过sqlServer的作业)
_LiuHui 2010-10-19
- 打赏
- 举报
点击关闭窗口页面 会有触发的JS代码。你可以在那里面写你需要的代码。即消除Session。
misswangjinfeng 2010-10-19
- 打赏
- 举报
//单人登入,即时登出
//首先设置web.config文件;
<sessionState mode="StateServer" cookieless="false" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" timeout="1"/>
//然后在登入事件中加入;
///同一时间点,检查登录用户ID的唯一性
///</summary>
///<param name="strZh">用户ID </param>
///<returns></returns>
private bool ckeckUserOnlyOne(string strZh)
{
string strTempZh=strZh;
if (Cache[strZh] == null)
{
TimeSpan SessTimeout = new TimeSpan(0,0,System.Web.HttpContext.Current.Session.Timeout,0,0);
HttpContext.Current.Cache.Insert(strTempZh,strTempZh,null, DateTime.MaxValue, SessTimeout, System.Web.Caching.CacheItemPriority.NotRemovable, null);
return true;
}
else
return false;
}
//复制代码
//然后在登出事件加入;
try
{
Session.Abandon();
System.Web.HttpContext.Current.Session.RemoveAll();
Cache.Remove("用户ID");
}
catch (Exception ex)
{ }
//复制代码
//主角登场了,在每个页面引入下面的JS;
<script>
var step=0;
function myRefresh()
{
var httpRequest = new ActiveXObject("microsoft.xmlhttp");
httpRequest.open("GET", "delSession.aspx", false);
httpRequest.send(null);
step ++;
if(step <2)//注意2
{
setTimeout("myRefresh()",30*1000); //30秒
}
}
myRefresh();
</script>
//项目的Root目录下new一个delSession.aspx文件,然后在她的page_laod方法中写上Response.Expires = -1;
//可以修改“step <2”和setTimeout("myRefresh()",30*1000),把这些参数放到配置文件中,可以随便修改
//首先设置web.config文件;
<sessionState mode="StateServer" cookieless="false" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" timeout="1"/>
//然后在登入事件中加入;
///同一时间点,检查登录用户ID的唯一性
///</summary>
///<param name="strZh">用户ID </param>
///<returns></returns>
private bool ckeckUserOnlyOne(string strZh)
{
string strTempZh=strZh;
if (Cache[strZh] == null)
{
TimeSpan SessTimeout = new TimeSpan(0,0,System.Web.HttpContext.Current.Session.Timeout,0,0);
HttpContext.Current.Cache.Insert(strTempZh,strTempZh,null, DateTime.MaxValue, SessTimeout, System.Web.Caching.CacheItemPriority.NotRemovable, null);
return true;
}
else
return false;
}
//复制代码
//然后在登出事件加入;
try
{
Session.Abandon();
System.Web.HttpContext.Current.Session.RemoveAll();
Cache.Remove("用户ID");
}
catch (Exception ex)
{ }
//复制代码
//主角登场了,在每个页面引入下面的JS;
<script>
var step=0;
function myRefresh()
{
var httpRequest = new ActiveXObject("microsoft.xmlhttp");
httpRequest.open("GET", "delSession.aspx", false);
httpRequest.send(null);
step ++;
if(step <2)//注意2
{
setTimeout("myRefresh()",30*1000); //30秒
}
}
myRefresh();
</script>
//项目的Root目录下new一个delSession.aspx文件,然后在她的page_laod方法中写上Response.Expires = -1;
//可以修改“step <2”和setTimeout("myRefresh()",30*1000),把这些参数放到配置文件中,可以随便修改
moudy 2010-10-19
- 打赏
- 举报
1.设置超时时间,如最后在线时间点超过10分钟再登陆即使状态为已登陆也允许再登陆,这要求在已登陆用户设置类似心跳包,隔多久在数据库中记录用户的最后在线时间点。
2.服务器异常,重启后想办法初始化该表所有状态为未登录(sqlSERVER可以用JOB实现)
2.服务器异常,重启后想办法初始化该表所有状态为未登录(sqlSERVER可以用JOB实现)
吴青峰 2010-10-19
- 打赏
- 举报
还判读这判读那些,你以为判断这些逻辑就很牛逼了,是不是!做一件事情,你判断再多,在复杂,让别人看不懂,是不是很有成就感。做事啊,要简单、易懂、快捷、灵活,当然了效率和安全性问题也要考虑。
吴青峰 2010-10-19
- 打赏
- 举报
不知道你程序怎么学的!
吴青峰 2010-10-19
- 打赏
- 举报
你傻了啊,把session的id直接存入数据库比你修改的状态更快吧。
加载更多回复(12)