无需从前端发送HTTP请求即可获取会话状态

时间:2018-09-24 10:57:07

标签: c# asp.net-core asp.net-identity asp.net-session

使用Reactjs + Redux + Saga设置ASP.NET Core。当asp.net核心会话过期时,它需要通知用户。但是问题是通过发送GET请求来检查会话状态,我们扩展了会话,这意味着除非关闭浏览器中的选项卡,否则会话将永远不会结束(然后将不发送GET请求)。这是会话设置Startup.cs

services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(60 * 60);
                options.Cookie.HttpOnly = true;
            });

然后我们每隔5分钟发送一次来自客户的请求以获取身份信息:

function* checkSessionIsValid() {
    try {
        const response = yield call(axios.get, 'api/Customer/FetchIdentity');

            if (!response.data) {
                return yield put({
                    type: types.SESSION_EXPIRED,
                });

            yield delay(300000);
            return yield put({ type: types.CHECK_SESSION_IS_VALID });
        }
        return;
    } catch (error) {
        return;
    }
}

和后端终结点(_context为IHttpContextAccessor):

        [HttpGet("FetchIdentity")]
        public LoginInfo GetIdentity()
        {
            if (SessionExtension.GetString(_context.Session, "_emailLogin") != null)
            {
                return new LoginInfo()
                {
                    LoggedInWith = "email",
                    LoggedIn = true,
                    Identity = ""
                };
            }

            return null;
        }

因此,我们从SessionExtension获取了会话信息。但是可能有某种方法可以在不连接到后端的情况下获得它?

2 个答案:

答案 0 :(得分:3)

您的要求是不可能的,坦率地说,当您了解会话的工作原理时,这毫无意义。会话仅在请求的上下文中存在。 HTTP是无状态协议。通过让服务器和客户端传递“会话ID”,会话实质上是伪造的状态。当服务器希望与客户端建立“会话”时,通常通过Set-Cookie响应标头向客户端发出会话ID。然后,客户端通常会通过Cookie请求标头在每个后续请求上传递此ID。服务器收到此ID后,便会从商店中查找相应的会话,然后可以访问以前处于播放状态的任何状态。

重点是,如果没有请求 first ,服务器将不知道或不在乎特定会话的状态。到期部分发生在服务器下一次尝试查找会话时。如果时间太长(会话过期已过去),则它将销毁上一个会话并创建一个新会话。它不会主动监视会话在特定时间执行任何操作。而且,由于您已注意到会话在滑动,因此到期时间范围内的每个请求都会重置该时间范围。结果,只要客户端一直在使用会话,会话就永远不会过期。

总之,了解会话状态的唯一方法是发出带有会话ID的请求,以提示服务器尝试恢复该会话。如果要跟踪客户端的会话过期,最好的方法是根据已知的超时设置计时器客户端。然后,您需要根据所有其他请求重设上述时间。

 var sessionTimeout = setTimeout(doSomething, 20 * 60 * 1000); // 20 minutes

然后,在您的AJAX回调中:

 clearTimeout(sessionTimeout);
 sessionTimeout = setTimeout(doSomething, 20 * 60 * 1000);

答案 1 :(得分:0)

也许可以使用SessionState属性。

[SessionState(SessionStateBehavior.Disabled)]

https://msdn.microsoft.com/en-US/library/system.web.mvc.sessionstateattribute.aspx?cs-save-lang=1&cs-lang=cpp

编辑:认识到您正在使用.NET Core,不确定当前是否存在SessionState属性或任何类似的东西。

相关问题