netcore cross-application distributed session

  • Demand scenario

    • Website a, domain name a.site.com
    • Website b, the domain name b.site.com
    • Session needs to be shared among a, b two sites
  • solution

    • Redis use as a distributed cache storage
    • Setting saved sessionId cookie domain name, so that the two sites Jun able to read the same sessionId
    services.AddDistributedRedisCache(options => //使用redis
    {
        options.Configuration = $"{conf},defaultDatabase={dbId}";
    });
    
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(30);
        options.Cookie.Domain = "site.com";
    });
    • Custom SessionMiddleware

      • Since SessionMiddleware Asp.net comes in the middle of the sessionid made encrypted, although the same results in different applications sessionId, but does not share the Session successful, specific details SessionMiddleware source member, wherein the class of CookieProtection encrypted 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;
            }
            ...
        }
      • Since SessionMiddleware is directly dependent class CookieProtection, it is necessary to re-implement their own middleware to handle the session, such as the realization of a MySessionMiddleware, you can achieve a shared 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;
            }
            ...
        }

Guess you like

Origin www.cnblogs.com/zcode/p/11563334.html