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

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

目录

前言:

1) 关于Http中的会话

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

一、配置会话中间件

二、会话状态的读写

三、 示例的生命周期

四、其他

前言:

本文使用 .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会话中间件的资料请关注易知道(ezd.cc)其它相关文章!

推荐阅读

    win7移动存储设备的读写速度加快

    win7移动存储设备的读写速度加快,,1、将你的移动存储设备插入USB端口,这时电脑会提示有新USB设备插入;2、右击“我的电脑”选择“属性”;3、

    bean生命周期的4个阶段是什么

    bean生命周期的4个阶段是什么,生命周期,方法,本文目录bean生命周期的4个阶段是什么java spring框架中,bean的生命周期是什么spring中bean

    LUA读写xml

    LUA读写xml,节点,文件,使用第三方库LuaXML操作xml 1、常用函数 xml.new(arg) 创建一个新的XML对象 xml.append(var,tag) 添加一个子节点 x

    5400转的硬盘读写速度

    5400转的硬盘读写速度,硬盘,读写,模式,文件,传输,连续,  市场上普遍的硬盘都是5400转或7200转这两个规格的,所以导致很多人在购买硬盘的时候很

    bug的生命周期是什么

    bug的生命周期是什么,缺陷,开发人员,确认,发现,跟踪,提交,BUG的生命周期就是一个BUG被发现到这个BUG被关闭的过程,具体过程为:1、发现BUG,即发现软

    默认的http超级文本传输协议端口是什么

    默认的http超级文本传输协议端口是什么,端口,服务,默认,输入,协议,网站,http协议的默认端口是“80端口”。80端口是为HTTP协议开放的,是网页服务

    线程的生命周期分几个阶段

    线程的生命周期分几个阶段,线程,执行,方法,调用,就绪,运行,5个阶段:1、新建,是刚使用new方法,new出来的线程;2、就绪,是调用的线程的start()方法后,这