我想出了一个很棒的解决方案。我实现的是用户“ Bob”从其PC登录,然后同一用户“
Bob”从另一个位置登录时,第一个位置(其PC)的登录将被杀死,而第二个位置登录以居住。用户登录后,它将一条记录插入我创建的名为“登录”的自定义表中。成功登录后,一条记录将插入到该表中,其中包含“
UserId,SessionId和LoggedIn”的值。UserId很不言自明,SessionId是当前会话ID(在获取方式中有解释),LoggedIn只是布尔值,在用户成功登录后最初设置为True。我把这个“插入”
Logins login = new Logins();login.UserId = model.UserName;login.SessionId = System.Web.HttpContext.Current.Session.SessionID;;login.LoggedIn = true;LoginsRepository repo = new LoginsRepository();repo.InsertOrUpdate(login);repo.Save();
对于我的情况,我想对每个控制器进行检查,以查看当前登录的用户是否已在其他位置登录,如果是,则终止其他会话。然后,当被终止的会话尝试导航到我将这些检查置于任何位置的位置时,它将注销它们并将其重定向到“登录”屏幕。
我有三种主要方法可以进行这些检查:
IsYourLoginStillTrue(UserId, SessionId);IsUserLoggedOnElsewhere(UserId, SessionId);LogEveryoneElseOut(UserId, SessionId);
将会话ID保存到会话[“ …”]
但是,在所有这些之前,我将SessionID保存到AccountController中
Login(
[HttpPost])方法中的Session集合中:
if (Membership.ValidateUser(model.UserName, model.Password)){ Session["sessionid"] = System.Web.HttpContext.Current.Session.SessionID;...
控制器代码
然后,我将逻辑放入控制器中,以控制这三种方法的执行流程。低于如果由于某种原因的通知
Session["sessionid"]是
null,它会只是单纯的为它分配一个值“空”。以防万一由于某种原因它返回为null:
public ActionResult Index(){ if (Session["sessionid"] == null) Session["sessionid"] = "empty"; // check to see if your ID in the Logins table has LoggedIn = true - if so, continue, otherwise, redirect to Login page. if (OperationContext.IsYourLoginStillTrue(System.Web.HttpContext.Current.User.Identity.Name, Session["sessionid"].ToString())) { // check to see if your user ID is being used elsewhere under a different session ID if (!OperationContext.IsUserLoggedOnElsewhere(System.Web.HttpContext.Current.User.Identity.Name, Session["sessionid"].ToString())) { return View(); } else { // if it is being used elsewhere, update all their Logins records to LoggedIn = false, except for your session ID OperationContext.LogEveryoneElseOut(System.Web.HttpContext.Current.User.Identity.Name, Session["sessionid"].ToString()); return View(); } } else { FormsAuthentication.SignOut(); return RedirectToAction("Login", "Account"); }}
三种方法
这些是我用来检查您是否仍在登录的方法(例如,确保您没有被其他登录尝试踢过),如果是,请检查您的用户ID是否已在其他地方登录,如果是的话,只需
false在“登录”表中将其“登录”
状态设置为即可将其启动。
public static bool IsYourLoginStillTrue(string userId, string sid){ CapWorxQuikCapContext context = new CapWorxQuikCapContext(); IEnumerable<Logins> logins = (from i in context.Logins where i.LoggedIn == true && i.UserId == userId && i.SessionId == sid select i).AsEnumerable(); return logins.Any();}public static bool IsUserLoggedOnElsewhere(string userId, string sid){ CapWorxQuikCapContext context = new CapWorxQuikCapContext(); IEnumerable<Logins> logins = (from i in context.Logins where i.LoggedIn == true && i.UserId == userId && i.SessionId != sid select i).AsEnumerable(); return logins.Any();}public static void LogEveryoneElseOut(string userId, string sid){ CapWorxQuikCapContext context = new CapWorxQuikCapContext(); IEnumerable<Logins> logins = (from i in context.Logins where i.LoggedIn == true && i.UserId == userId && i.SessionId != sid // need to filter by user ID select i).AsEnumerable(); foreach (Logins item in logins) { item.LoggedIn = false; } context.SaveChanges();}
编辑
我也只想补充一点,此代码将忽略“记住我”功能的功能。我的要求不涉及此功能(实际上,出于安全原因,我的客户不想使用此功能),因此我将其遗漏了。尽管有了一些额外的编码,我很确定可以将其考虑在内。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)