Asp.net MVC - How to check session expiration for an Ajax request

We use the Ajax call through the application, trying to find a global solution to redirect to the login page if the session has already expired, trying to fulfill any Ajax request. I coded the following solution, helping out of this post - Handling session timeout in ajax calls

NOT SURE WHY IN MY EVENT "HandleUnauthorizedRequest" IS NOT RECEIVED.

User attribute:

 [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);
            }

        }

    }

Using the above custom attribute as specified in the controller action:

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

AJAX Call (JS part):

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

        },
        error: function (xhr, ajaxOptions, thrownError) {

        }
}

Web configuration authentication settings:

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

I try to check it by deleting the browser before making an ajax call, but the "CheckSessionExpireAttribute" event does not fire - any idea.

Thanks,

@Paul

+6
5

, . , ajax .

Ajax, .

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

            },
            error: function (xhr, ajaxOptions, thrownError) {

            }
        });
    }
0

HttpContext.Request.IsAjaxRequest()

, , Ajax .

XMLHttpRequest() IsAjaxRequest?

, (X-Requested-With), true.

, , , .

, ? , .

- . , , , , . , -, , , , - .

cookie 30 . . 20 .

- ASP.NET

HandleUnauthorizedRequest

0

, . - . , ( 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'
       }
    }
});
0

, : , , . , :

  • , 2 : ,
  • Ajax, : ( , Ajax / / , )
  • , . Ajax , , " ", Redirect ( "url here" ).
  • , 2 (return Redirect(), return Json, Xml, Object string)

, , :

  • 1. ajax
  • 2. ajax, , . , ( ajax- = )
0

( , , ), , , , , 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);
}

Then in your client function (I took the privilege to write it as $.get()instead of $.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");
        });
    });
});

This function replaces the html tag with this attribute data-ajax-render-html, which contains the address of the view you want to load, but you can set it to load inside the tag by changing the replaceWithproperty html().

0
source

All Articles