【问题标题】:How to set sliding expiration in MVC 5 application如何在 MVC 5 应用程序中设置滑动过期
【发布时间】:2019-02-11 18:54:19
【问题描述】:

我有一个使用 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)
        {

        }
    }

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    如果 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);
            }
        }
    }
    

    【讨论】:

    • 在你的情况下,这意味着会话永远不会过期!
    • 15分钟后服务器没有请求就会过期。
    【解决方案2】:

    您也可以使用 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() 的正文标记中。您还可以将 onmousemove 添加到调用 ResetTimer() 的主体标记中,这样只要页面上有活动,就不会触发超时。如果在页面上没有看到鼠标活动,则显示对话框,如果检测到移动,则关闭对话框并重置计时器。 或者您也可以处理按键事件来重置计时器。

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

    您也可以从 javascript 调用 MVC Action。

    【讨论】:

    • 能否提示并通知用户他或她的会话即将到期?
    • 函数 IdleWarning() 将执行此操作。您可以在此处编写自己的对话框打开代码,此函数将在 14 分钟后调用。您可以从变量“timoutWarning”中更改值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2020-06-19
    • 2020-05-08
    • 1970-01-01
    相关资源
    最近更新 更多