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;
              }
              ...
          }
          
  • 相关阅读:
    跨域问题(使用jsonp解决)
    通用Mapper使用(Maven+SSM)
    hosts文件修改(域名和IP地址对应修改)
    ExportExcel(用poi导出Excel文件:用List<Map<String,Object>>)
    activiti已结束子流程退回
    一个数据库死锁的案例
    mysql函数使用的例子
    mybatis拦截器
    Objects工具类
    Spring Boot 中读取配置属性
  • 原文地址:https://www.cnblogs.com/zcode/p/11563334.html
Copyright © 2011-2022 走看看