zoukankan      html  css  js  c++  java
  • netcore 实现跨应用的分布式session

    • 需求场景

      • 网站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;
              }
              ...
          }
          
  • 相关阅读:
    kafka 消息推送报错"dial tcp: lookup iZ2ze2k3******7abjcsyZ on 219.141.140.10:53: no such host"
    MacBook安装Homebrew的国内安装脚本 告别龟速下载安装
    docker info命令的使用和返回结果描述
    Python requests.post方法中data与json参数区别
    redis master-slave python switch logic (升级版,序列七)
    ELKF日志收集系统
    MySQL 中的concat函数使用
    程序员的街舞“梦”
    第一份工作没有工资,信不信
    Java中的享元设计模式,涨姿势了!
  • 原文地址:https://www.cnblogs.com/zcode/p/11563334.html
Copyright © 2011-2022 走看看