ASP.NET MVC-如何查看AJAX请求的会话到期



我们在整个应用程序上使用ajax调用 - 如果在尝试执行任何AJAX请求时已经过期会话,请尝试将全局解决方案重定向到登录页面。我已经在解决这篇文章的帮助下进行了编码 - 在AJAX呼叫中处理会话超时

不确定为什么在我的护理活动中" handerunauthorizedRequest"不会被解雇。

自定义属性:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class CheckSessionExpireAttribute :AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var url = new UrlHelper(filterContext.RequestContext);
                var loginUrl = url.Content("/Default.aspx");
                filterContext.HttpContext.Session.RemoveAll();
                filterContext.HttpContext.Response.StatusCode = 403;
                filterContext.HttpContext.Response.Redirect(loginUrl, false);
                filterContext.Result = new EmptyResult();
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }
    }

在控制器操作中使用上述自定义属性如下:

 [NoCache]
 [CheckSessionExpire]
 public ActionResult GetSomething()
 {
  }

AJAX调用(JS Part):

function GetSomething()
{
   $.ajax({
        cache: false,
        type: "GET",
        async: true,
        url: "/Customer/GetSomething",
        success: function (data) {
        },
        error: function (xhr, ajaxOptions, thrownError) {
        }
}

Web配置身份验证设置:

  <authentication mode="Forms">
      <forms loginUrl="default.aspx" protection="All" timeout="3000" slidingExpiration="true" />
    </authentication>

我尝试通过删除浏览器烹饪来检查它,然后再进行ajax呼叫,但事件" checksessionexpireattribute"不会被解雇 - 请任何想法。

谢谢,

@paul

如果我的问题正确(即使我不这样做,也要,谢谢,都帮助我解决了自己的情况),您要避免的是将您的登录页面加载到一个元素中,该元素应该通过Ajax显示不同的视图。在AJAX表单帖子中获得异常/错误状态代码。

因此,简而言之,注释类将需要覆盖2种方法,而不仅仅是HandleUnauthorizedRequest,并且它将重定向到JSONRESULT操作,该操作将为您的Ajax函数生成参数以了解该怎么做。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class SessionTimeoutAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        IPrincipal user = filterContext.HttpContext.User;
        base.OnAuthorization(filterContext);
        if (!user.Identity.IsAuthenticated) {
            HandleUnauthorizedRequest(filterContext);
        }
    }
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new RedirectToRouteResult(new
            RouteValueDictionary(new { controller = "AccountController", action = "Timeout" }));
        }
    }
}

然后在您的身份验证操作中设置此注释,因此每次调用它时,都会知道请求来自何处,以及它应该给出的返回。

[AllowAnonymous]
[SessionTimeout]
public ActionResult Login() { }

然后您重定向的JSON动作:

[AllowAnonymous]
public JsonResult Timeout()
{
    // For you to display an error message when the login page is loaded, in case you want it
    TempData["hasError"] = true;
    TempData["errorMessage"] = "Your session expired, please log-in again.";
    return Json(new
    {
        @timeout = true,
        url = Url.Content("~/AccountController/Login")
    }, JsonRequestBehavior.AllowGet);
}

然后在您的客户端功能中(我享有将其写入$.get()而不是$.ajax()的特权:

$(document).ready(function () {
    $("[data-ajax-render-html]").each(function () {
        var partial = $(this).attr("data-ajax-render-html");
        var obj = $(this);
        $.get(partial, function (data) {
            if (data.timeout) {
                window.location.href = data.url;
            } else {
                obj.replaceWith(data);
            }
        }).fail(function () {
            obj.replaceWith("Error: It wasn't possible to load the element");
        });
    });
});

此功能用此data-ajax-render-html属性替换HTML标签,其中包含要加载的视图地址,但是您可以通过更改html()属性的replaceWith来将其设置为在标签中加载。

我认为这只是一个客户端问题。在Web服务器中,您只需使用经典授权属性而不是动作或控制器。这将验证该请求为 authenticated (如果有有效的身份验证cookie或授权标题),并设置http 401(如果未进行认证)。

注意:如果您不在请求中发送授权信息,则会自动重新创建会话,但不会授权请求

解决方案

然后javascript客户端您必须处理重定向(浏览器会自动执行此操作,但使用AJAX,您需要手动执行)

$.ajax({
    type: "GET",
    url: "/Customer/GetSomething",
    statusCode: {
       401: function() {
          // do redirect to your login page
          window.location.href = '/default.aspx'
       }
    }
});

我检查并测试了代码,看起来很清楚。问题是Ajax调用是错误的。

我修复了Ajax代码,尝试此..

function GetSomething() {
        $.ajax({
            cache: false,
            type: "GET",
            async: true,
            url: "/Customer/GetSomething",
            success: function (data) {
            },
            error: function (xhr, ajaxOptions, thrownError) {
            }
        });
    }

on httpcontext.request.isajaxrequest()

请参阅此相关文章,介绍为什么可能不认为Ajax请求。

xmlhttprequest()未公认为isajaxrequest?

看起来有一个依赖性对某个标题值(x-重新值)的依赖性,以使该函数返回true。

您可能需要捕获和查看服务器的流量和标题,以查看浏览器是否正确发送了此值。

但是,您是否确定它会击中该行的代码?您可能还希望使用 debug 使用 break> break> break point 设置值。

在会话vs authentication

授权和会话超时并不总是完全相同。实际上,可以比会议更长的时间授权授权,如果会议丢失,只要已经授权,就可以重建授权。如果您发现会议上的某些东西要失去无法重建的东西,那么也许您应该将其移动到其他地方,或者还将其持续到其他地方。

形式身份验证 cookies默认为 30分钟后>超时。 session 超时默认值为 20分钟

asp.net中的会话超时

handerunauthorizedRequest不覆盖

很抱歉:您需要的解决方案是不可能的。原因是:

  • 要重定向用户登录页面,我们有2种方法:在服务器上重定向,在客户端重定向
  • 在您的情况下,您使用的是Ajax,所以我们只有1种方法:在客户端重定向(基本上是Ajax是指将数据发送/从服务器发送/检索到服务器。因此,无法在服务器上重定向)
  • 接下来,在客户端重定向。Ajax需要从服务器中获取信息,这些信息说"重定向用户到登录页",而全局检查会话方法必须返回重定向(" url there there")。
  • 显然,全局检查会话方法无法返回2 type(return redirect(),返回JSON,XML,对象或字符串)

毕竟,我建议:

  • 解决方案1 :不要使用ajax
  • 解决方案2 :您可以使用AJAX,但请检查服务器上的会话超时方法,该方法不是全球。意味着您必须多次实施(AJAX呼叫的数量=实施数)

最新更新