如何通过JavaScript检测MVC 3会话到期 [英] How To Detect MVC 3 Session Expiration via JavaScript

查看:60
本文介绍了如何通过JavaScript检测MVC 3会话到期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MVC 3网站,会话超时为2分钟.

如果用户在2分钟内未与页面互动,则应在点击2分钟后自动将其转发到登录屏幕(而不是在2分钟后互动).

在会话仍处于活动状态时,只要用户与页面互动,会话超时都需要从该时间重置为2分钟.

我们当前的实现如下(源代码如下):
1.用户登录时,调用setTimeout(checkSession,120000)
2.当用户与页面交互时,调用renewSession()
3.运行checkSession()后,调用setTimeout(checkSession,120000)

当前实现中的问题是,存在一个漏洞,该会话将在2分钟以上的时间内有效.

例如:
-用户在12:00登录(会话应在12:02终止)
-用户在12:01与页面互动
-调用续订会话,它将会话超时重置为2分钟(会话应在12:03到期)
-在12:02,第一个checkSession()运行并返回有效,checkSession()设置为在12:04再次运行
-会话仍应在12:03到期,但这不是因为checkSession()也会更新会话超时
-如果用户在12:04之前未与网站互动,则checkSession()将运行并注销用户,但是距上次用户活动已经3分钟了

我最初的解决方法是在调用renewSession()时调用setTimeout(checkSession,120000),但是由于checkSession()会更新会话,因此可以使其永远存活.

总有办法阻止checkSession更新会话,还是有人可以为我指出实现此目的的更好解决方案?

$(document).ready(function() {
    setTimeout("checkSession();", 60000);

    $("body").mouseup(function () {
        renewSession();
    });

    $("input").blur(function () {
        renewSession();
    });

    $("input").focus(function () {
        renewSession();
    });
});

function checkSession() {
    $.ajax({
        url: "/Account/CheckIfSessionValid",
        type: "POST",
        success: function (result) {
            if (result == "False") {
                window.location = "/Account/LogOff";
            }
        },
        complete: function () {
            setTimeout("checkSession();", 60000);
        }
    });
} 

function renewSession() {
    $.ajax({
        url: "/Account/RenewSession",
        type: "POST",
        data: {
            __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val()
        }
    });
}

public ActionResult CheckIfSessionValid()
{
    if (Session["GoldenTicket"] == null)
    {
        Session.RemoveAll();
        Session.Abandon();
        FormsAuthentication.SignOut();
        return Json("False");
    }

    return Json("True");
}

[HttpPost]
[ValidateAntiForgeryToken]
public void RenewSession()
{
    Session["GoldentTicket"] = "True";
}


protected void Session_End(object sender, EventArgs e)
{
    Session.Clear();
    Session.Abandon();
    Session.RemoveAll();
}

解决方案

var checkTimeout;

$(document).ready(function () {
    checkTimeout = setTimeout(checkSession, 900000);
});

function checkSession() {
    $.ajax({
        url: "/Account/CheckIfSessionValid",
        type: "POST",
        success: function (result) {
            if (result == "False") {
                window.location = "/Account/LogOff";
            }
        },
        complete: function () {
            setupSessionTimeoutCheck();
        }
    });
}

function setupSessionTimeoutCheck() {
    clearTimeout(checkTimeout);
    checkTimeout = setTimeout(checkSession, 900000);
}

I have an MVC 3 site with a session timeout of 2 minutes.

If the user doesn't interact with the page within 2 minutes, they should be automatically forwarded to the login screen as soon as 2 minutes hits (not when they interact after 2 minutes).

Any time the user interacts with the page while the session is still active, the session timeout needs to be reset to 2 minutes from that time.

Our current implementation is as follows (source code is below):
1. When user logs in, call setTimeout(checkSession, 120000)
2. When the user interacts with the page, call renewSession()
3. After checkSession() runs, call setTimeout(checkSession, 120000)

The issue in the current implementation is that, there is a loophole where the session will be valid for longer than 2 minutes.

For example:
- user logs in at 12:00 (session should expire at 12:02)
- at 12:01 the user interacts with the page
- renew session is called which resets the session timeout to 2 minutes (session should expire at 12:03)
- at 12:02, first checkSession() runs and returns valid, checkSession() gets set to run again at 12:04
- session should still expire at 12:03, but it doesn't because checkSession() is also renewing the session timeout
- if user doesnt interact with site before 12:04, checkSession() will run and log the user off, however, it's been 3 minutes since the last user activity

My initial solution was to call setTimeout(checkSession, 120000) when renewSession() is called but since checkSession() renews the session this keeps it alive forever.

Is there anyway to prevent checkSession from renewing the session or can someone point me to a better solution for accomplishing this?

$(document).ready(function() {
    setTimeout("checkSession();", 60000);

    $("body").mouseup(function () {
        renewSession();
    });

    $("input").blur(function () {
        renewSession();
    });

    $("input").focus(function () {
        renewSession();
    });
});

function checkSession() {
    $.ajax({
        url: "/Account/CheckIfSessionValid",
        type: "POST",
        success: function (result) {
            if (result == "False") {
                window.location = "/Account/LogOff";
            }
        },
        complete: function () {
            setTimeout("checkSession();", 60000);
        }
    });
} 

function renewSession() {
    $.ajax({
        url: "/Account/RenewSession",
        type: "POST",
        data: {
            __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val()
        }
    });
}

public ActionResult CheckIfSessionValid()
{
    if (Session["GoldenTicket"] == null)
    {
        Session.RemoveAll();
        Session.Abandon();
        FormsAuthentication.SignOut();
        return Json("False");
    }

    return Json("True");
}

[HttpPost]
[ValidateAntiForgeryToken]
public void RenewSession()
{
    Session["GoldentTicket"] = "True";
}


protected void Session_End(object sender, EventArgs e)
{
    Session.Clear();
    Session.Abandon();
    Session.RemoveAll();
}

解决方案

var checkTimeout;

$(document).ready(function () {
    checkTimeout = setTimeout(checkSession, 900000);
});

function checkSession() {
    $.ajax({
        url: "/Account/CheckIfSessionValid",
        type: "POST",
        success: function (result) {
            if (result == "False") {
                window.location = "/Account/LogOff";
            }
        },
        complete: function () {
            setupSessionTimeoutCheck();
        }
    });
}

function setupSessionTimeoutCheck() {
    clearTimeout(checkTimeout);
    checkTimeout = setTimeout(checkSession, 900000);
}

这篇关于如何通过JavaScript检测MVC 3会话到期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆