Session 詳解

 

Session 詳解

引子

想一個問題, 有一個商店要作一個活動,對於在本店累計消費超過2000元的客戶 ,能夠領取小禮品一份。要如何實現 。php

  1. 每次消費給客戶一張消費憑證如發票等 ,用戶兌獎把這些發票都帶過來 。
  2. 給客戶辦一張會員卡,客戶結帳時出示會員卡,收銀員能夠在商店的管理系統查到客戶的歷史消費記錄 ,而後兌獎。

是什麼

字面意思 會話(對話) ,會話機制 ,客戶端發起對話,服務端回答,通過屢次對話後,讓服務端擁有知道以前和某個客戶聊了什麼的機制 。java

其餘web

  • session 是一種服務端機制 ;
  • 由於http協議無狀態,全部須要狀態管理 ( 記得上一講 ,爲何有cookie 也是這個緣由麼 );
  • 不一樣web平臺都有對session機制的實現;

創建會話:redis

客戶端請求服務端,服務端檢測這邊有沒有存儲和這個客戶的對話。若是沒有就創建會話 ,有的話繼續維護當前會話。(思考問題,經過什麼檢測有沒有和這個客戶的對話)算法

斷開會話:sql

服務端銷燬某個會話數據,會使其斷開;客戶端長時間不訪問服務端,根據配置的session過時時間,服務端會銷燬和某個客戶端會話數據。
同時,客戶端也能夠斷開會話,只須要客戶端不告訴服務端sessionid,或者換一個開啓一段新的會話。數據庫

分清楚一個概念:會話狀態和登陸狀態的區別

會話狀態雖然經常被用來標識登陸狀態。可是卻不能徹底等同 ;登陸狀態很好理解,用戶沒有登陸以前,是未登陸狀態。 輸入帳號密碼(或其餘方式)登陸驗證成功以後是 已登陸狀態。
那何時開始有會話狀態的呢 ?
舉一個例子來證實沒有登陸,會話狀態已經產生了 :好比登陸或者註冊時的圖形驗證碼 。c#

不一樣web平臺中對session的實現

不一樣web開發框架都有對session機制的 實現,或者叫封裝 ,常見的平臺以下圖:windows

平臺 核心對象 默認存放sessionId的cookie name 使用語法
c# System.Web.SessionState.HttpSessionState ASP.NET_SessionId Session[""]=3;
php $_SESSION PHPSESSID $_SESSION['33']=1;
java javax.servlet.http.HttpSession JSESSIONID HttpSession session = request.getSession(); session.setAttribute("data", "sfe");

Asp.net 對Session的實現

咱們從Session在web.config文件中的配置講起:參考跨域

  • session在web.config中的配置
<sessionState
mode= "[Off|InProc|StateServer|SQLServer|Custom]"
timeout= "number of minutes"
cookieName= "session identifier cookie name"
cookieless=
"[true|false|AutoDetect|UseCookies|UseUri|UseDeviceProfile]"
regenerateExpiredSessionId= "[True|False]"
sessionIDManagerType= "session manager type"
sqlConnectionString= "sql connection string"
sqlCommandTimeout= "number of seconds"
allowCustomSqlDatabase= "[True|False]"
useHostingIdentity= "[True|False]"
stateConnectionString= "tcpip=server:port"
stateNetworkTimeout= "number of seconds"
customProvider= "custom provider name"
compressionEnabled= "[True|False]"
sqlConnectionRetryInterval= "number of seconds">
<providers>... </providers>
</sessionState>

挑幾個關鍵屬性講下:

  • mode
    • Off: 關閉,不使用cookie
    • InPro: 當前進程,也就是w3wp進程
    • SQLServer :會話狀態正在使用進程外 SQL Server 數據庫存儲狀態信息。Aspnet_regsql.exe 工具
    • StateServer:會話狀態將使用進程外 ASP.NET 狀態服務來存儲狀態信息, windows服務aspnet_state.exe
    • Custom : 自定義,本身實現SessionStateStoreProviderBase這個抽象類就能夠了,而後配置:
<sessionState mode="Custom" customProvider="MySessionStateStore">
<providers>
<clear/>
<add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider" connectionString="RedisConnection"/>
</providers>
</sessionState>
  • cookieless
    • AutoDetect :session機制根據瀏覽器對cookie的支持狀況決定是使用cookie仍是url傳遞sessionid
    • UseCookies :顯式指定使用cookie 傳遞sessionid【推薦
    • UseDeviceProfile :session機制根據瀏覽器對cookie的支持狀況決定是使用cookie仍是url傳遞sessionid
    • UseUri: 顯式指定用url傳遞sessionid

常見Session丟失緣由

一、Session超時,用戶打開頁面,頁面長時間不操做會致使此緣由

二、IIS應用程序池回收,或者重啓

三、Web.Config修改,即IIS應用程序池重啓

四、dll被替換或者動態頁面修改,即IIS應用程序池重啓

五、殺毒軟件對.config文件進行掃描,可能會致使IIS應用程序池回收

六、用戶瀏覽器禁用cookie

七、其餘緣由

asp.net Session 進階

Session 共享

兩個網站會話共享, a網站登陸,b網站也登陸了,根據session的原理 ,session是經過客戶端的cookie裏的sessionid 來識別同一個用戶發來的請求,因此這裏這裏就是要連個網站sessionid同樣 ,也就是cookie相同,可是cookie是不能跨域傳輸的,可是隻要主域同樣 ,將cookie的域設置成domain.com ,cookie會發送到這個主域下全部子域對應的網站。
是否發送到兩個網站服務端的sessionid同樣,session就共享了呢,其實否則 ,
若是session mode 是Inpro 模式,這明顯不行,由於session存在各自的網站進程裏面,
若是session mode是 stateServer模式呢 ,其實也不行,須要進行一些小修改就好,由於session的存儲結構不僅僅是 sessionid 和session裏面的內容 ,他是sessionid 和網站惟一標誌共同來惟一指定的,咱們能夠經過一些手段騙session機制,兩個不一樣的網站的惟一標誌是同樣的。
session mode 是sqlserver 和上面的方案差很少,也是要進行些修改,讓網站標誌同樣 。
能夠看到實現session的共享仍是很麻煩的。

  1. 設置存儲sessionid的cookie的域是主域
  2. 將session存在 stateserver 或者sqlserver (性能會有所影響) ,
  3. 騙asp.net session機制,不一樣網站的網站惟一標誌是同樣的。

網站負載了 Session 還可用麼

這個問題還須要有負載均衡相關知識才能瞭解,簡而言之,一樣的web程序部署多個,客戶端發出的請求根據算法分配到其中某一個服務端處理。
首先能夠肯定,發送到多個程序的sessionid是同樣的,接着就是服務端能根據sessionid獲取到一樣的會話數據嗎?
這個問題和上面很像 ,是不能的,由於網站的標誌不同的。說解決方案也和上面差很少了,少了第一步。

Session 的併發缺點

微軟官方的幾種sessionmode provider 都有這個問題,在一段會話裏面 ,服務端會按照循序處理客戶端發過來的會話請求 ,也就是說,上一個請求沒處理完,瀏覽器就發起了下一個請求的話會被掛起,直到上一個會話請求處理完成。這種併發狀況可能常見於一個頁面上對服務端發出多個異步請求,若是某個請求處理時間很長 ,後面就請求就會被掛起。雖然.net 提供了關閉某個地址session的配置,可是一般業務場景中都是須要會話狀態的。

不用Asp.net Session 用什麼

咱們把這個問題轉換一下,由於

常見的session使用場景是

  1. 存儲驗證碼
  2. 存儲用戶基礎信息,如id ,姓名,角色等
  3. 做爲身份驗證,登陸驗證
  4. 多個頁面間傳值
  5. ???

那麼就是找處處理這些場景問題解決方案就能夠了 。
能不能把用cookie加密存儲。 或者cache +cookie ,redis +cookie ,
另外身份驗證能夠用。net自帶 forms 身份驗證。

Q&A

  1. 爲何session(若是做爲登陸狀態,那就會形成從新登陸)莫名其妙丟失 ?
  2. 向session裏面寫數據時報錯 ,沒法序列化
    沒法序列化會話狀態。在「StateServer」或「SQLServer」模式下,ASP.NET 將序列化會話狀態對象,所以不容許使用沒法序列化的對象或 MarshalByRef 對象。若是自定義會話狀態存儲在「Custom」模式下執行了相似的序列化,則適用一樣的限制。
  3. 用來承載會話的cookie ,有什麼特徵。
  4. 若是讓你實現一個簡單的session機制須要作哪些事 。
相關文章
相關標籤/搜索