如何在MVC 5应用程序中设置滑动到期

时间:2019-02-11 10:20:14

标签: c# asp.net-mvc

我有一个使用MVC 5构建的应用程序,在这种情况下,即使用户仍在文本框中键入内容,但默认会话超时时间已过,仍将用户重定向到登录页面。我希望仅当页面闲置超过15分钟时才将用户重定向到登录页面,而不是在用户非常闲置时才重定向到登录页面。在Web表单中,我们用于在配置文件中将滑动过期设置为true,但这在MVC中不起作用。我将不胜感激。

这是我尝试过的:

[HttpPost]
 [AllowAnonymous]

public ActionResult Login(LoginViewModel model, string returnUrl, string 
command)
   {
     string decodedUrl = "";
      if (!string.IsNullOrEmpty(returnUrl))
      decodedUrl = Server.UrlDecode(returnUrl);
      FormsAuthentication.SetAuthCookie(model.Email, false);

     var authTicket = new FormsAuthenticationTicket(1, user.Email,
     DateTime.Now, DateTime.Now.AddMinutes(15), false, user.Roles);
     string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
     var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,
     encryptedTicket);
     HttpContext.Response.Cookies.Add(authCookie);
     authCookie.Expires = authTicket.Expiration;

      if (Url.IsLocalUrl(decodedUrl))
          {
               return Redirect(decodedUrl);
          }
         else
          {
           return RedirectToAction("analytics", "dashboard");
         }
 }

全球ASAX代码:

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        try
        {
    var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                if (authTicket != null && !authTicket.Expired)
                {
                    var roles = authTicket.UserData.Split(',');
                    HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
                }
            }
        }
        catch(Exception ex)
        {

        }
    }

2 个答案:

答案 0 :(得分:0)

您也可以使用javascript来实现。

// Set timeout variables.
var timoutWarning = 840000; // Display warning in 14 Mins.
var timoutNow = 900000; // Timeout in 15 mins.
var logoutUrl = '<url>'; // URL to logout page.

var warningTimer;
var timeoutTimer;

// Start timers.
function StartTimers() {
    warningTimer = setTimeout("IdleWarning()", timoutWarning);
    timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}

// Reset timers.
function ResetTimers() {
    clearTimeout(warningTimer);
    clearTimeout(timeoutTimer);
    StartTimers();
    $("#timeout").dialog('close');
}

// Show idle timeout warning dialog.
function IdleWarning() {
    $("#timeout").dialog({
        modal: true
    });
}

// Logout the user.
function IdleTimeout() {
    window.location = logoutUrl;
}

基本上将onload添加到调用StartTimers()的body标记中。您还可以在body标签上添加onmousemove,该标签调用ResetTimer(),以便只要页面上存在活动,就不会触发超时。如果在页面上没有看到鼠标活动,则在检测到移动时显示对话框,对话框将关闭并且计时器重置。 或者您也可以处理按键事件以重置计时器。

<body onload="StartTimers();" onmousemove="ResetTimers();">

您还可以从javascript调用MVC Action。

答案 1 :(得分:0)

如果cookie过期而没有对服务器发出任何请求,那么我认为您无能为力。在您的示例中,当用户在文本框中键入内容时被踢出门时,服务器如何知道他们正在这样做?

假设有 个请求正在服务器上运行,请在您的Application_PostAuthenticateRequest处理程序中,仅检查是否有有效的现有故障单,剩余时间少于X,如果是这样,则通过将其添加到响应中来发布新的。

遵循以下原则:

if (authCookie != null)
{
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    if (authTicket != null && !authTicket.Expired)
    {
        var roles = authTicket.UserData.Split(',');

        var user = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);

        HttpContext.Current.User = user;

        // Issue new ticket if there is less than 7 minutes remaining on current one.
        if ((authTicket.Expires - DateTime.Now) <= TimeSpan.FromMinutes(7)) 
        {
            var authTicket = new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(15), false, user.Roles);

            string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

            var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

            HttpContext.Response.Cookies.Add(authCookie);
        }
    }
}