原文:
SignOnMode.cs
#region // ----------------------------------------------------------------- // 版权所有:Copyright(C) // 文件名称:SignOnMode.cs // 系统名称: // 模块名称: // 作 者:Keasy // 完成日期:2015/12/24 // 功能描述: // ----------------------------------------------------------------- // 修 改 者: // 修改日期: // 修改描述: // ----------------------------------------------------------------- #endregion using System; using System.Collections; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using DocumentFormat.OpenXml.Packaging; namespace Chinasap.Columbus.Common.Function.Login { /// <summary> /// 登录方式类 /// </summary> /// <remarks> /// 同一账号是否能在多处登录帮助类 /// </remarks> public static class SignOnMode { /// <summary> /// 在线信息Application标识 /// </summary> private const string OnlineAppFlag = "Online"; private const string InvalidSessionFlag = "INVALIDSESSION"; /// <summary> /// 添加登录信息 /// </summary> /// <param name="signOnToken"> /// 登录令牌:用于标识用户信息的唯一标识,一般是用户的id /// </param> public static void RegisterSignOn(string signOnToken) { Hashtable hOnline = (Hashtable)HttpContext.Current.Application[OnlineAppFlag]; if (hOnline != null) { IDictionaryEnumerator enumerator = hOnline.GetEnumerator(); string sessionId = ""; while (enumerator.MoveNext()) { if (enumerator.Value != null && enumerator.Value.ToString().Equals(signOnToken)) { /* * 将当前用户Id对应的会话(Session.SessionID唯一标识) * 都设置为无效会话 */ sessionId = enumerator.Key.ToString(); hOnline[sessionId] = InvalidSessionFlag; //无效会话 break; } } } else { hOnline = new Hashtable(); } //将当前"登录"用户Id对应的会话设置为有效会话 hOnline[HttpContext.Current.Session.SessionID] = signOnToken; HttpContext.Current.Application.Lock(); HttpContext.Current.Application["Online"] = hOnline; HttpContext.Current.Application.UnLock(); } /// <summary> /// 执行登录规则 /// </summary> /// <returns> /// 是否退出登录: /// true:表示当前登录需要当前强制退出 /// 否则:当前当前登录不需要退出 /// </returns> public static bool ExecuteSignOnRule() { bool forcedLogout = false; //是否需要强制退出当前登录 // 配置:同一账号是否能在多处登录 string canMultipleLogin = ConfigurationManager.AppSettings["CanMultipleLogin"]; if (canMultipleLogin != null && canMultipleLogin.ToLower() == "true") { return false; //同一账号可以能在多处登录 } Hashtable hOnline = (Hashtable)HttpContext.Current.Application["Online"]; if (hOnline != null && HttpContext.Current.Session != null) { IDictionaryEnumerator enumerator = hOnline.GetEnumerator(); while (enumerator.MoveNext()) { var sessionId = enumerator.Key; var sessionVal = enumerator.Value; if (sessionId != null && sessionId.ToString().Equals(HttpContext.Current.Session.SessionID)) { if (sessionVal != null && InvalidSessionFlag.Equals(sessionVal.ToString())) { /*删除无效会话*/ hOnline.Remove(HttpContext.Current.Session.SessionID); HttpContext.Current.Application.Lock(); HttpContext.Current.Application["Online"] = hOnline; HttpContext.Current.Application.UnLock(); //帐号已在别处登陆,被强迫下线! HttpContext.Current.Session[SessionKeys.LoginUser] = null; forcedLogout = true; } break; } } } return forcedLogout; } /// <summary> /// 清除无效登录信息 /// </summary> /// <remarks> /// 一般用于Global.asax.cs的函数: /// protected void Session_End(object sender, EventArgs e) /// 中调用,使得在Session过期或者退出系统时释放资源 /// </remarks> public static void ClearInvalidSignOn() { if (HttpContext.Current != null) { Hashtable hOnline = (Hashtable)HttpContext.Current.Application["OnlineAppFlag"]; if (hOnline != null) { if (HttpContext.Current.Session != null) { if (hOnline[HttpContext.Current.Session.SessionID] != null) { hOnline.Remove(HttpContext.Current.Session.SessionID); HttpContext.Current.Application.Lock(); } } } } } } }
使用:
第一步:在登录成功后,记录登录信息
SignOnMode.RegisterSignOn(user.Id);
public string Login(LoginViewModel model,bool rememberAccount) { //....... if(登录成功) { SignOnMode.RegisterSignOn(user.Id); } //....... }
第二步:
在需要登录的地方执行
bool forcedLogout = SignOnMode.ExecuteSignOnRule();
public override void OnActionExecuting(ActionExecutingContext filterContext) { var _url = "~/Home/Index"; if (SessionHelper.GetSession(SessionKeys.LoginUser) == null) { filterContext.Result = new RedirectResult(_url); } else { #region 同一账号不能多处登录 /*-------------------------------------------------------------------------- 同一账号不能多处登录 *--------------------------------------------------------------------------*/ bool forcedLogout = SignOnMode.ExecuteSignOnRule(); if (forcedLogout) { filterContext.Result = new RedirectResult(_url); } #endregion } }
第三步:在Session过期或者(异常)退出系统时,释放资源释放资源,做法是:
在Global.asax.cs的函数:
protected void Session_End(object sender, EventArgs e)
中调用,使得在Session过期或者退出系统时释放资源
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { .... } protected void Session_End(object sender, EventArgs e) { /*-------------------------------------------------------------------------- 同一账号不能多处登录 *--------------------------------------------------------------------------*/ /*在Session过期或者退出系统时释放资源*/ SignOnMode.ClearInvalidSignOn(); } }
第四步:
在配置文件添加中添加“同一账号是否能多处登录”的开关。
<appSettings> <!--配置:同一账号是否能多处登录,true表示可以多点登陆--> <add key="CanMultipleLogin" value="false" /> </appSettings>
完毕。
时间: 2024-08-07 17:00:18