欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

netcore 实现跨应用的分布式session

程序员文章站 2022-07-02 13:14:31
需求场景 网站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;
            }
            ...
        }