检查用户是否已登录asp.net网站

我正在开发一个网站,用户需要登录系统才能使用它。 当前function是:当用户输入用户名和密码时,在DB中进行检查以检查该用户是否存在以及是否输入了正确的密码。 只有这样才允许该用户登录。

到目前为止一切正常,现在客户端想要为日志记录function添加一个function,即客户端希望仅限制该用户存在1个会话。

即。 如果user1从PC的一个浏览器登录,则不允许他从另一个系统或同一PC的另一个浏览器登录。

我怎么做? 我计划使用我的数据库中的位字段来完成它,这将在用户第一次登录时设置。 如果他尝试记录第二次检查该字段并且仅在未设置位字段时允许登录。

但我觉得它会引起问题,

1)如果用户错误地关闭浏览器的选项卡并尝试再次登录,则无法执行此操作,因为仍会在DB中设置位字段

2)如果用户误将浏览器关闭,何时清除设置字段?

如果有任何其他方式来实现它,那么你可以自由地指出我正确的方向。

正如一些成员所指出的那样,这个问题有重复,但这些问题并不是我想要的,因为they are using form based authentication and I am not

您可以像IsLoggedIn一样向userTable添加列。 在登录时,您可以更改为true,并在global.asax上的Session_End事件上将其更改为false

要提供有关我评论的更多详细信息:

步骤1

创建包含以下字段的Sessions表:

 SessionId ( Primary Key ) char(24) UserId ( Foreign Key to Users table ) int LoginDate datetime 

第2步

创建Session类。

 public class Session { public string Sessionid { get; set; } public int UserId { get; set; } public DateTime LoginDate { get; set; } } 

第3步

如果你有一个名为DoLogin的函数。

 public void DoLogin() { //validation commes here... //create your session Session["User"] = user; //user is your User class object //create session class for db Session session = new Session(); session.SessionId = ""; //you can generate here a 24 character string session.UserId = user.Id; session.LoginDate = DateTime.Now; db.Add(session); //add session to db } 

第4步

创建一个函数来检查用户是否已登录。

 public bool IsLoggedIn(User user) { Session session = db.GetSession(user.Id); //Get session of the user if(session != null) { return true; } else { return false; } } 

不要试图通过将值存储在datatbase中来解决此类问题,而是尝试一种会话方法。

在登录页面或默认页面中,选择使用会话登录的用户(即会话[“用户名”] =“某些登录用户”)

现在加载每个经理页面检查会话的有效性如下

 if(!mCheckStatusOfSession()) { Response.Redirect("To Login Page") } protected void mCheckStatusOfSession{ if (Application[Session["UserName"].ToString()] == null) { return false; } else { Application[Session["UserName"].ToString()].ToString(); if (strID == Session.SessionID.ToString()) { return true; } else { return false; } } } 

1)用户登录后,我们使用用户名+密码作为缓存项的密钥来检查缓存。 如果Cache项存在,我们知道登录已经在使用中,所以我们将它们踢出去。 否则,我们对它们进行身份validation(数据库等)并让它们进入。

2)在我们让它们进入之后,我们设置一个新的Cache项目条目,其中包含一个由用户名+密码组成的密钥,其滑动到期时间等于当前的Session Timeout值。 我们还可以设置一个新的Session变量Session [“user”],其值为username + password,这样我们就可以在用户会话期间对每个页面请求进行连续页面请求检查和缓存更新。 这为我们提供了“复制”缺少的Session_Endfunction的基础结构。

3)现在我们需要一种方法来更新每个页面请求的缓存过期时间。 您可以在Global中的Application_PreRequestHandlerExecute处理程序中非常优雅地执行此操作,因为Session对象在此处理程序中可用且“活动”。 此外,每个页面请求都会触发此事件,因此我们不需要在任何页面中添加一行额外代码。 我们使用Session [“user”]值来获取此用户的密钥以检索其缓存项,从而重置它并自动将滑动到期时间设置为新的超时值。 每当您访问Cache项时,其SlidingExpiration属性(如果配置正确)都会自动更新。 当用户放弃他们的会话并且在一段时间内没有请求页面时,他们的缓存项的SlidingExpiration最终到期,并且该项自动从缓存中移除,从而允许具有相同用户名和密码的人再次登录。 没有大惊小怪,没有麻烦! 适用于InProc,StateServer和SQL Server会话模式!

参考文章: 1,2,3

这就是我在@Satinder singh提供的链接的帮助下@Satinder singh

的Global.asax.cs

  protected void Application_Start(object sender, EventArgs e) { Application["UsersLoggedIn"] = new System.Collections.Generic.List(); } protected void Session_End(object sender, EventArgs e) { // NOTE: you might want to call this from the .Logout() method - aswell -, to speed things up string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"]; if (userLoggedIn.Length > 0) { System.Collections.Generic.List d = Application["UsersLoggedIn"] as System.Collections.Generic.List; if (d != null) { lock (d) { d.Remove(userLoggedIn); } } } } 

Login.aspx.cs

 protected bool Login(string userId) { System.Collections.Generic.List d = Application["UsersLoggedIn"] as System.Collections.Generic.List; if (d != null) { lock (d) { if (d.Contains(userId)) { // User is already logged in!!! string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"]; if (userLoggedIn == user_id) { Session["UserLoggedIn"] = user_id; return true; } else { return false; } } else { string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"]; if (userLoggedIn != user_id) { d.Add(userId); } } } } Session["UserLoggedIn"] = userId; return true; } 

使用上面的代码,我允许任何用户只能在任何时间登录一次。 我使用会话变量检查请求是否来自同一个浏览器,如果是这样,我允许他/她登录,否则抛出一条消息“你已经从另一个系统登录”。