asp.net core session丟失問題排查


       最近公司采用asp.net core的站點在外測環境中,總是發現存在session丟失的情況。排查了好久,客戶端.AspNetCore.Session的cookie未丟失,session的分布式緩存采用的redis主從復制也未發現問題,也想用cookie的變通解決方案,但是沒解決根本問題,總是覺得如魚梗在喉的不爽。后來在排查的過程中,發現同一個客戶端通過nginx居然有時候會負載到不同的網站服務器上,檢查過nginx,是通過ip_hash進行轉發的啊,迷惑不解之際,公司的運維一語破的,原來公司是采用雙線路由器的。於是猜測,是否因為存儲cookie加密的key存在不同服務器上所導致。

       打開微軟的Session的源碼,先查看SessionMiddleware中間件的代碼,其中有以下的關鍵源碼:

var cookieValue = context.Request.Cookies[_options.CookieName];
            var sessionKey = CookieProtection.Unprotect(_dataProtector, cookieValue, _logger);
            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;
            }
sessionKey是從客戶端的cookie中解密出來的,其中CookieProtection的_dataProtector來自
_dataProtector = dataProtectionProvider.CreateProtector(nameof(SessionMiddleware));
將系統默認注入的IDataProtectionProvider扒出來:

發現IDataProtectionProvider為Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider,該IDataProtectionProvider的keyManager為
Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager。


果然不出所料,key存在單機上,打開微軟的DataProtection-dev源碼查看FileSystemXmlRepository中獲取Key存儲路徑的實現:

眼尖的發現項目下面就有一個將key持久化到redis的實現:

添加相應的nuget包,修改ConfigureServices方法:
            services.AddDataProtection()
                .PersistKeysToRedis(ConnectionMultiplexer.Connect(redisConnection), dataProtectionKey);
終於完美解決!在采用分布式存儲session的時候,最好將dataProtectionProvider的key也進行共享,否則如果做了ip_hash負載均衡,客戶端ip一變,可能負載到另外一台服務器,導致存儲session的cookie數據解密不出來從而獲取不到session!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM