我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ASP.NETCore中间件会话状态读写及生命周期示例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ASP.NETCore中间件会话状态读写及生命周期示例

前言:

本文使用 .NET Core SDK 3.1 的版本。

1) 关于Http中的会话

  • Http是一种采用请求响应消息交换模式,且无状态的传输协议。
  • 该协议确保客户端将请求报文发送给目标服务器并接收来自服务端的响应报文,这个报文交换是一个Http事务。
  • 从协议的角度讲,即使在使用长连接的情况下,同一个客户端和服务器之间进行多个Http事务也是完全独立的
  • 所以需要在应用层为两者去建立一个上下文来保存多次消息交换的状态,这就是所谓的会话。

2) 关于 ASP.NET Core 中的会话

  • 在 ASP.NET Core 中利用一个叫做 Session 的中间件来实现会话,
  • 每个会话都有一个标识SessionKey,但是SessionKey不是唯一标识,是一个数据字典的形式,
  • 将SessionKey保存在服务端,当会话中间件在处理会话的第一个请求的时候,会创建一个SessionKey
  • 并基于它创建一个独立的数据字典来存储会话状态,应用程序设置的会话状态都是自动保存在当前会话对应的数据字典中的
  • 这个SessionKey最终会以 Cookie 的形式写入响应并返回给客户端,
  • 客户端在每次发起请求的时候都会附加这个 Cookie,从而使我们的应用程序能够准确定位到当前会话对应的数据字典。

一、配置会话中间件

配置基于内存的分布式缓存服务和会话服务,如需要将缓存放置于数据库可以参考微软官方文档

	public void ConfigureServices(IServiceCollection services)
	{
		// 添加基于内存的缓存服务,以供会话中间件来使用
        collection.AddDistributedMemoryCache();
        // 添加会话
        collection.AddSession();
	}

添加会话中间件

	public void Configure(IApplicationBuilder app)
	{
		// 引入会话中间件
		app.UseSession();
	}

二、会话状态的读写

写入Session

    ISession session = httpContext.Session;
    var sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
    session.SetString("SessionStartTime", sessionStartTime);

读取Session

    ISession session = httpContext.Session;
    session.TryGetValue("SessionStartTime", out var value);
    var sessionStartTime = Encoding.UTF8.GetString(value);

获取SessionId

    ISession session = httpContext.Session;
    session.TryGetValue("SessionStartTime", out var value);
    var sessionStartTime = Encoding.UTF8.GetString(value);

获取SessionKey

SessionKey 需要通过反射获取

    ISession session = httpContext.Session;
    var field = typeof(DistributedSession).GetTypeInfo()
        .GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
    var sessionKey = field?.GetValue(session);

三、 示例的生命周期

这里准备了示例的代码:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/get", async httpContext =>
        {
            ISession session = httpContext.Session;
            string sessionStartTime;
            if (session.TryGetValue("SessionStartTime", out var value))
            {
                sessionStartTime = Encoding.UTF8.GetString(value);
            }
            else
            {
                sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                session.SetString("SessionStartTime", sessionStartTime);
            }
            var field = typeof(DistributedSession).GetTypeInfo()
                .GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
            var sessionKey = field?.GetValue(session);
            var responseText = $@"
                <html>
                <body>
                    <h1>Get Session</h1>
                    <ul>
                        <li>Session ID:{session.Id}</li>
                        <li>Session Key:{sessionKey}</li>
                        <li>Session Start Time:{sessionStartTime}</li>
                        <li>Current Time:{DateTime.Now:yyyy-MM-dd HH:mm:ss}</li>
                    </ul>
                </body>
                </html>";
            httpContext.Response.ContentType = "text/html";
            await httpContext.Response.WriteAsync(responseText);
        });
    });

清除浏览器中的 Cookie,然后刷新页面进入/get页面中,可以看到在新的网络请求中响应标头多了一个 set-cookie,这个set-cookie是被加密的SessionKey,还具有 httponly 的标签,以防止Cookie 的值被跨站读取。

默认请求下 Cookie 采用的路径是根路径

然后我们重新刷新页面,可以看到请求标头中多出一个 cookie,就是之前的 set-cookie,因为之前缓存被清除以后,第一次刷新标头多一个 set-cookie,相当于创建一个新的会话,当下一次发起请求就会带上 cookie。

四、其他

  • SessionId 可以作为会话的唯一标识,但是 SessionKey 不可以
  • 也就是说两个不同的 Session,肯定具有不同的 SessionId,但是他们有可能共享相同的SessionKey
  • 当会话中间件接收到会话的第一个请求的时候,他会创建两个不同的 guid,分别表示 SessionKey 和 SessionId
  • 其中 SessionId 将被作为会话状态的一部分被存储起来,而 SessionKey 则会以会话的形式返回给客户端
  • 会话一般都是有有效期的,而会话的有效期基本决定了存储的会话状态数据的有效期
  • 默认情况下 ASP.NET Core 应用的会话它所采用的默认过期时间是20分钟, 默认情况下20分钟内的任意请求都会将会话的寿命延长再延长
  • 两次请求的时间超过了有效期,意味着这个会话过期,存储的会话状态数据包括 SessionId 也都会被清除
  • 但是请求携带的 SessionKey 可能还是原来的 SessionKey
  • 在这种请求下,会话中间件会创建一个新的会话,这个新的会话具有不同的 SessionId,但是整个会话状态仍然会沿用原来的 SessionKey
  • 所以 SessionKey 不能作为会话的唯一标识,它只代表存储数据的标识
  • 会话本质上就是在应用的层面上提供了一个数据容器来保存客户端的状态,这个客户端状态就是会话状态,会话的核心功能就是会话状态的读写

以上就是ASP.NET Core中间件会话状态读写及生命周期示例的详细内容,更多关于ASP.NET Core会话中间件的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ASP.NETCore中间件会话状态读写及生命周期示例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录