需求場景 網站a,功能變數名稱為 a.site.com 網站b, 功能變數名稱為 b.site.com 需要在a、b兩個站點之間共用session 解決方案 使用redis作為分散式緩存存儲 設置sessionId cookie 保存的功能變數名稱,使得兩個網站鈞能夠讀取到相同的sessionId 自定義SessionMi ...
需求場景
- 網站a,功能變數名稱為 a.site.com
- 網站b, 功能變數名稱為 b.site.com
- 需要在a、b兩個站點之間共用session
解決方案
- 使用redis作為分散式緩存存儲
- 設置sessionId cookie 保存的功能變數名稱,使得兩個網站鈞能夠讀取到相同的sessionId
services.AddDistributedRedisCache(options => //使用redis { options.Configuration = $"{conf},defaultDatabase={dbId}"; }); services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.Domain = "site.com"; });
自定義SessionMiddleware
由於Asp.net 自帶的SessionMiddleware中間中對sessionid做了加密處理,導致不同應用雖然sessionId相同,但是並不能成功的共用Session,具體詳件SessionMiddleware源碼,其中使用了CookieProtection類的對sessionId進行了加密
public async Task Invoke(HttpContext context) { .... if (string.IsNullOrWhiteSpace(sessionKey) || sessionKey.Length != SessionKeyLength) { // No valid cookie, new session. var guidBytes = new byte[16]; CryptoRandom.GetBytes(guidBytes); sessionKey = new Guid(guidBytes).ToString(); cookieValue = CookieProtection.Protect(_dataProtector, sessionKey); var establisher = new SessionEstablisher(context, cookieValue, _options); tryEstablishSession = establisher.TryEstablishSession; isNewSessionKey = true; } ... }
由於SessionMiddleware是直接依賴類CookieProtection,因此需要重新實現自己的中間件來處理session,比如實現一個MySessionMiddleware,即可實現session共用
public async Task Invoke(HttpContext context) { .... if (string.IsNullOrWhiteSpace(sessionKey) || sessionKey.Length != SessionKeyLength) { // No valid cookie, new session. var guidBytes = new byte[16]; CryptoRandom.GetBytes(guidBytes); sessionKey = new Guid(guidBytes).ToString(); cookieValue = Md5(sessionKey);//此處可以使用自己的加密規則,重要的是保證不同的應用,通過加密規則生成的值是相同的 var establisher = new SessionEstablisher(context, cookieValue, _options); tryEstablishSession = establisher.TryEstablishSession; isNewSessionKey = true; } ... }