原文:数组
SignOnMode.csapp
#region // ----------------------------------------------------------------- // 版权全部:Copyright(C) // 文件名称:SignOnMode.cs // 系统名称: // 模块名称: // 做 者:Keasy5 // 完成日期:2015/12/24 9:51:10 // 功能描述: // ----------------------------------------------------------------- // 修 改 者: // 修改日期: // 修改描述: // ----------------------------------------------------------------- #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 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[OnlineAppFlag] = hOnline; HttpContext.Current.Application.UnLock(); } /// <summary> /// 是否须要强制退出当前登陆 /// </summary> /// <returns> /// 是否退出登陆: /// true:表示当前登陆须要当前强制退出 /// 不然:当前当前登陆不须要退出 /// </returns> public static bool NeedForceSignOut() { bool needForcedSignOut = false; //是否须要强制退出当前登陆 // 配置:同一帐号是否能在多处登陆 string canMultipleLogin = ConfigurationManager.AppSettings["CanMultipleLogin"]; if (canMultipleLogin != null && canMultipleLogin.ToLower() == "true") { return false; //同一帐号能够能在多处登陆 } Hashtable hOnline = (Hashtable)HttpContext.Current.Application[OnlineAppFlag]; 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[OnlineAppFlag] = hOnline; HttpContext.Current.Application.UnLock(); //账号已在别处登录,被强迫下线! needForcedSignOut = true; } break; } } } return forcedSignOut; } /// <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(); } } } } } } }
文件:SessionKeys.cs
/// <summary> /// 系统级别Session名称 /// </summary> public static class SessionKeys { /// <summary> /// 存储用户登陆的session名常量 /// </summary> public const string LoginUser = "LoginUser"; }
文件SessionHelper.cside
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; namespace xxxx { /// <summary> /// Session 操做类 /// 一、GetSession(string name)根据session名获取session对象 /// 二、SetSession(string name, object val)设置session /// </summary> public class SessionHelper { /// <summary> /// 根据session名获取session对象 /// </summary> /// <param name="name"></param> /// <returns></returns> public static object GetSession(string name) { return HttpContext.Current.Session[name]; } /// <summary> /// 设置session /// </summary> /// <param name="name">session 名</param> /// <param name="val">session 值</param> public static void SetSession(string name, object val) { if (KeysContains(name)) { HttpContext.Current.Session[name] = val; } else { HttpContext.Current.Session.Add(name, val); } } /// <summary> /// 判断Key值在当前Session是否是已经存在 /// </summary> /// <param name="key"></param> /// <returns></returns> private static bool KeysContains(string key) { if (HttpContext.Current.Session != null) { foreach (var item in HttpContext.Current.Session.Keys) { if (item != null && item.Equals(key)) return true; } } return false; } /// <summary> /// 添加Session,调动有效期为20分钟 /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <param name="strValue">Session值</param> public static void Add(string strSessionName, object strValue) { HttpContext.Current.Session[strSessionName] = strValue; HttpContext.Current.Session.Timeout = 120; } /// <summary> /// 添加Session,调动有效期为20分钟 /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <param name="strValues">Session值数组</param> public static void Adds(string strSessionName, string[] strValues) { HttpContext.Current.Session[strSessionName] = strValues; HttpContext.Current.Session.Timeout = 120; } /// <summary> /// 添加Session /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <param name="strValue">Session值</param> /// <param name="iExpires">调动有效期(分钟)</param> public static void Add(string strSessionName, object strValue, int iExpires) { HttpContext.Current.Session[strSessionName] = strValue; HttpContext.Current.Session.Timeout = iExpires; } /// <summary> /// 添加Session /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <param name="strValues">Session值数组</param> /// <param name="iExpires">调动有效期(分钟)</param> public static void Adds(string strSessionName, string[] strValues, int iExpires) { HttpContext.Current.Session[strSessionName] = strValues; HttpContext.Current.Session.Timeout = iExpires; } /// <summary> /// 读取某个Session对象值 /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <returns>Session对象值</returns> public static string Get(string strSessionName) { if (HttpContext.Current.Session[strSessionName] == null) { return null; } else { return HttpContext.Current.Session[strSessionName].ToString(); } } /// <summary> /// 读取某个Session对象值数组 /// </summary> /// <param name="strSessionName">Session对象名称</param> /// <returns>Session对象值数组</returns> public static string[] Gets(string strSessionName) { if (HttpContext.Current.Session[strSessionName] == null) { return null; } else { return (string[])HttpContext.Current.Session[strSessionName]; } } /// <summary> /// 删除某个Session对象 /// </summary> /// <param name="strSessionName">Session对象名称</param> public static void Del(string strSessionName) { HttpContext.Current.Session[strSessionName] = null; } /// <summary> /// 获取Session 过时时间 /// </summary> /// <returns></returns> public static int SessionTimeout(string sessionTimeoutConfigString) { string sessionTimeout = sessionTimeoutConfigString; if (string.IsNullOrWhiteSpace(sessionTimeout)) { //若是为空,默认30 return 30; } return Convert.ToInt32(sessionTimeout); } } }
使用:函数
第一步:在登陆成功后,记录登陆信息url
SignOnMode.RegisterSignOn(user.Id);spa
public string Login(LoginViewModel model,bool rememberAccount) { //....... if(登陆成功) {
HttpContext.Current.Session[SessionKeys.LoginUser] = ....;//用户登陆信息,若是该值为null,视为没有登陆
SignOnMode.RegisterSignOn(user.Id);
}
//.......
}
第二步:code
在须要登陆的地方执行 orm
bool forcedLogout = SignOnMode.NeedForceSignOut();
这里是定义个筛选器,而后在使用在Controller上。
public override void OnActionExecuting(ActionExecutingContext filterContext) { var _url = "~/Home/Index"; if (HttpContext.Current.Session[SessionKeys.LoginUser] == null) { filterContext.Result = new RedirectResult(_url); } else { #region 同一帐号不能多处登陆 /*-------------------------------------------------------------------------- 同一帐号不能多处登陆 *--------------------------------------------------------------------------*/ bool needForceSignOut = SignOnMode.NeedForceSignOut(); if (needForceSignOut) {
HttpContext.Current.Session[SessionKeys.LoginUser] = null; //用户登陆信息,若是该值为null,视为没有登陆 filterContext.Result = new RedirectResult(_url); } #endregion } }
[LoginFilter] public class BaseController : Controller { ...... }
第三步:在Session过时或者(异常)退出系统时,释放资源释放资源,作法是:对象
在Global.asax.cs的函数:
protected void Session_End(object sender, EventArgs e)
中调用:
SignOnMode.ClearInvalidSignOn();
使得在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>
完毕。