原文:數組
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>
完畢。