怎么判断一个用户只能登陆一次?

cjhazn 2006-08-24 09:39:11
使用Application记录当前登陆用户ID,当正常关闭IE时可以从中去掉用户ID
如果非正常关闭IE,怎么把用户ID去掉。 
Session_End里可以去掉ID,但是Session失效时间不能设置太短
正常关闭IE后,又可以再次登陆

有没有方法解决
谢~~~~~~~~~~
第一次发贴,帮帮
...全文
1649 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
cjhazn 2006-09-03
  • 打赏
  • 举报
回复
谢谢大家的帮忙,最后有点忙,没上来看,想不到有这么多的朋友帮助,感激~~~
问题解决了,可是项目经理说方法不太好,他说要改为cashe做,具体怎么实现还不太清楚,
他还在研究!

我是用thirdman(大肥猪)的这个方法做的
给每在线用户增加一个RefreshTime属性,建立一个负责将当前用户的RefreshTime属性设置为当前时间的单独页面(Refresh.aspx),然后在系统的主要页面(也可以是所有页面)中通过xmlhttp不断地请求Refresh.aspx页面,一旦用户关闭了与本系统相关的所有窗口,即以直接关闭浏览器的方式退出系统,那么该用户的RefreshTime属性便不会自动更新了,我们再设置一个自动刷新的超时时间(这个要比会话超时短很多_refreshTimeout),当发现某用户超过_refreshTimeout的时间没有自动刷新,就能判定该用户已经以直接关闭浏览器的方式退出了。

结贴
lxwin01 2006-08-29
  • 打赏
  • 举报
回复
怎么还没结贴啊
lxwin01 2006-08-28
  • 打赏
  • 举报
回复
在线用户列表你可以用单例的方式来实现,或者保存在Application中,保证它在你的系统中只有一个实例来维持列表.
你先要关心的用户怎么登录和退出的问题,举个例子,登录login.aspx,框架页面index.htm包含有top.aspx,leftframe.aspx,rightframe.aspx,online.aspx,登录验证后进行这个index.htm页面在这个框架页面中你想办法将index.htm关闭时执行注销操作,正如我上面写的javascript脚本
<script language="javascript" for="window" event="onunload">
window.open("logout.aspx");
</script>
调用的logout.aspx去注销,在用户列表中删除当前在线用户。
online.aspx这个页面负责在线操作,如用户列表的刷新,它将每隔一段时间进行刷新页面。
即便非法退出online也会去验证在线用户,如(你可以定义操作一定时间没有响应的用户,认为他已经退出)
接下来如何实现在系统中同一帐号不重复登录
你可以在用户列表存储一些信息,来和登录后保存在session中的一些信息是否匹配,来实现
如:
IP地址,在登录时,将用户登录的IP地址存放在session中,和用户在线列表中,将在列表中找有此用户则更新,无此用户添加到列表中
online.aspx来实现踢出重复帐号,当前同一帐号,最后一个登录的用户一定更新了在线列表的信息,那么原来session中的ip和列表中用户信息的ip就会不同,如果不同就提示并退出.

xjjdanran 2006-08-25
  • 打赏
  • 举报
回复
UP
阿牛138588 2006-08-25
  • 打赏
  • 举报
回复
登录两次有什么不妥呢?要不在登录之前先删除一下ID,登录时再写上
endstar520 2006-08-25
  • 打赏
  • 举报
回复
留名
xray2005 2006-08-25
  • 打赏
  • 举报
回复
收藏!
fengfangfang 2006-08-25
  • 打赏
  • 举报
回复
另外,一个userid在该表中最多只能有一条记录
fengfangfang 2006-08-25
  • 打赏
  • 举报
回复
将userid sessionid ipaddress actionTime存到一个表里面,只有当用户的sessionid ipaddress和userid对应,才是在线的用户,否则就需要重新登录

使用job对此表进行actionTime超过一定时间的用户进行清除
xiaoyaowp 2006-08-25
  • 打赏
  • 举报
回复
收藏
fds2003 2006-08-25
  • 打赏
  • 举报
回复
关注!!
zlkingdom 2006-08-25
  • 打赏
  • 举报
回复
这是一个老问题了,再次收藏下
luyesql 2006-08-25
  • 打赏
  • 举报
回复
关注
myminimouse 2006-08-25
  • 打赏
  • 举报
回复
关注
hoodlum521 2006-08-25
  • 打赏
  • 举报
回复
代码已经发到楼主的邮箱了。。
再贴一个供大家参考吧!!



Global.asax:

void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
Hashtable ht = new Hashtable();
Application["onlineuser"] = ht;
Application["onlinecount"] = 0;
}
  
void Session_Start(object sender, EventArgs e)
{
// 在新会话启动时运行的代码
Application.Lock();
Application["onlinecount"] = int.Parse(Application["onlinecount"].ToString()) + 1;
Application.UnLock();
}

void Application_AuthenticateRequest(object sender, EventArgs e)
{
try
{
Hashtable ht = (Hashtable)Application["onlineuser"];
bool isAlive = false;
foreach (string key in ht.Keys)
{
if (key == (User.Identity.Name + "%%" + Request.UserHostAddress))
{
isAlive = true;
break;
}
}
if (!isAlive && Request.IsAuthenticated)
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
return;
}
else if (isAlive && Request.IsAuthenticated)
{
ht.Remove(User.Identity.Name + "%%" + Request.UserHostAddress);
ht.Add(User.Identity.Name + "%%" + Request.UserHostAddress, DateTime.Now.ToString());
Application["onlineuser"] = ht;
}
}
catch (Exception ee)
{
//Response.Write(ee.Message);
}
}
void Session_End(object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
Application.Lock();
Application["onlinecount"] = int.Parse(Application["onlinecount"].ToString()) - 1;
Application.UnLock();
}

用户登录时验证:注意应该是先验证密码,然后再验证,是否登录,最后验证权限!

bool logined = false;
if (logined)
{//验证是否允许重复登陆。
Hashtable ht = (Hashtable)Application["onlineuser"];
string tmpKey = "";
foreach (string key in ht.Keys)
{
if (key.Substring(0, key.LastIndexOf("%%")) == Login1.UserName)
{
if (key.Substring(key.LastIndexOf("%%") + 2) == Request.UserHostAddress) break;
else if (DateTime.Parse(ht[key].ToString()).AddMinutes(10) >= DateTime.Now)
{
Response.Write("<script>alert('你已在IP:" + key.Substring(key.LastIndexOf("%%") + 2) + " 上登陆,请在该机上点击注销以退出登陆。');</script>");
logined = false;
break;
}
else
{
tmpKey = key;
}
}
}
if (tmpKey != "")
{
ht.Remove(tmpKey);
}
try
{
if(logined)ht.Add(Login1.UserName + "%%" + Request.UserHostAddress, DateTime.Now.ToString());
}
catch { }
Application["onlineuser"] = ht;
}
hoodlum521 2006-08-25
  • 打赏
  • 举报
回复
我觉得往数据库里写数据不明智吧!!
如果用户一直登录不注销怎么办??
或者不小心把浏览器关了怎么办??
岂不是再也登录不了!!
Peng_Liang 2006-08-25
  • 打赏
  • 举报
回复
跟进学习中
lxwin01 2006-08-25
  • 打赏
  • 举报
回复
你可以创建一个用户列表(HashTable)以键/值存放,登录验证有效并添加不用多说了。
你加一个框架页面,在close的时候注销掉你的当前用户如:
<script language="javascript" for="window" event="onunload">
window.open("logout.aspx");
</script>
我这里是调用了logout.aspx去注销。
你可以在框架页面中嵌入一个一直刷新的页面在此页面中进行验证和其它在线操作。
charles_y 2006-08-25
  • 打赏
  • 举报
回复
thirdman(大肥猪)
--------------------------
给每在线用户增加一个RefreshTime属性,建立一个负责将当前用户的RefreshTime属性设置为当前时间的单独页面(Refresh.aspx),然后在系统的主要页面(也可以是所有页面)中通过xmlhttp不断地请求Refresh.aspx页面,一旦用户关闭了与本系统相关的所有窗口,即以直接关闭浏览器的方式退出系统,那么该用户的RefreshTime属性便不会自动更新了,我们再设置一个自动刷新的超时时间(这个要比会话超时短很多_refreshTimeout),当发现某用户超过_refreshTimeout的时间没有自动刷新,就能判定该用户已经以直接关闭浏览器的方式退出了。


-----------------------------------------------------------------------------------------------
这个是最好的解决方法
erwanfan 2006-08-24
  • 打赏
  • 举报
回复
我上面所说的情况,只需要在页面初始响应和页面onunload时去做操作,相比使用每一小段时间就去后台操作来说,要好很多,也同样也没有session的timeout限制。实际也一样需要ajax去操作。具体ajax使用方法,可以参照一下http://blog.joycode.com/kaneboy/archive/2004/07/07/26914.aspx(javascript调用后台代码)!
加载更多回复(24)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧