【问题标题】:.Net MVC - Display "session expired" only for private pages.Net MVC - 仅为私人页面显示“会话已过期”
【发布时间】:2013-07-10 22:18:04
【问题描述】:

我正在开发一个 .NET MVC 4 应用程序,如果用户在会话超时后执行某些操作,该应用程序需要向用户显示“会话过期”消息。

我正在使用超时时间很长的表单身份验证和超时时间较短的会话,因此我可以知道会话是否已过期或者它是新访问者。这是我的 Web.config 部分:

<authentication mode="Forms">
  <forms loginUrl="~/Login" timeout="10080" defaultUrl="~/Index" />
</authentication>
<sessionState mode="InProc" timeout="20" />

正如我所说,这只是为了区分新访问者和会话超时,而不是应用程序本身所必需的。如果用其他方法可以达到相同的结果,则可以更改它。

在 Web.config 中,我可以在 Global.asax 中执行以下操作:

protected void Session_Start(object sender, EventArgs e)
{
    //if it's a new session AND the user is authenticated, then it's a session timeout
    if (Request.IsAuthenticated)
    {
        if (Request.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            //...
            //Ajax handling code
            //...
            //The redirect is so I can return a JsonResult with a standard object with the message
            Response.Redirect("/GetJson?some_parameters, true);
        }
        else
        {
            Response.Redirect("/SessionExpired", true);
        }
    }
}

所有这些都适用于需要登录的网站的私人部分。问题是,如果用户登录,等待会话超时,然后尝试打开一个不需要登录的“公共”页面,他仍然会收到“会话过期”消息。这就是我想要避免的。只有当用户尝试访问需要登录的页面时,才应向用户显示“会话过期”消息。

我尝试在 Session_Start 中设置一个标志并在稍后的 Global.asax 事件中重定向,但它不起作用,因为我遇到了一些可变的可访问性问题。 我想尝试检查当前操作是否具有[AllowAnonymous] 属性,以便我可以跳过重定向,但我不知道如何。 我阅读的一些答案给我的印象是我的“会话过期”逻辑应该在自定义属性中,但我不知道这是否是正确的方法。

我的问题是,为 .Net MVC 4 中的“私有”页面完成“会话过期”的最佳方法是什么?

【问题讨论】:

    标签: asp.net-mvc-4 session


    【解决方案1】:

    正如您所说,理想的情况是使用属性。更准确地说,这个属性被命名为“Action Filter”。

    您可以创建一个实现接口的 ActionFilter,或继承现有接口。

    在您的情况下,我认为获得结果的最简单方法是继承 AuthorizeAttribute,并覆盖其 OnAuthorization 方法。

    在此方法中,您可以将HttpContext 作为filterContext 参数的属性访问:filterContext.HttpContext。您可以使用此属性检查会话、授权并检查它是否是 ajax 请求。如果需要重定向,必须通过设置filterContext参数的属性来实现:

    filterContext.Result = new RedirectResult("...url to redirect to...");
    

    您可以使用RedirectResultRedirectToRouteResult 构造函数的任何重载。

    如果您保持Result 属性不变,则不会发生任何特别的事情。

    您可以使用此自定义属性代替原始授权属性。

    【讨论】:

    • 有没有办法在操作过滤器中知道会话是否刚刚在此请求中创建?否则...如何知道用户是新访问者还是会话已过期的旧访问者?
    • 您可以使用自定义 cookie 作为标志。您可以注册一个全局操作过滤器来处理这个 cookie。如果请求中不存在您的自定义 cookie,并且用户有会话,则将您的 cookie 设置为“新会话”。如果 cookie 已经存在于请求中,并且会话处于活动状态,则将其更改为“旧会话”。如果 cookie 存在,但会话已过期,则将其标记为“上一个会话已过期”。您不必完全按照这种方式进行操作,这只是您可以做什么的草图。
    • 谢谢,我过几天试试,告诉你效果如何。
    猜你喜欢
    • 2012-01-15
    • 2012-12-18
    • 1970-01-01
    • 2012-02-05
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 2016-08-04
    相关资源
    最近更新 更多