简体   繁体   中英

How to make entire page redirect to login after session expires in mvc?

I have this attribute overridden and decorated it on each controller which does its job perfectly on all normal views:

public class MyAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authroized = base.AuthorizeCore(httpContext);
        if (!authroized)
        {
            // the user is not authenticated or the forms authentication
            // cookie has expired
            return false;
        }

        // Now check the session:
        var checkUser = httpContext.Session["LoggedUserID"];

        if (checkUser == null)
        {
            // the session has expired
            return false;
        }

        return true;
    }
}

And I have this one of many cases where I need to update a certain partial view within a parent view:

<script type="text/javascript">
$(function () {
    $(".sensor-delete-table").on("click", function () {
        var divSensorNames = $("#sensorNames");
        var tr = $(this).parents('tr:first');
        var PredefineViewsItemID = tr.find("#PredefineViewsItemID").html();
        var PredefineViewID = tr.find("#PredefineViewID").html();
        var amount = parseInt($("[data-id='" + PredefineViewID + "']").text());
        var flag = confirm('@Html.Localize("deleteCheck")');
        var urlShowNewSensors = "@Url.Action("ShowSensorNames", "PredefinedViews", new { predefinedViewID = "PredefineViewID" })";
        urlShowNewSensors = urlShowNewSensors.replace("PredefineViewID", PredefineViewID);
        if (PredefineViewID != "" && flag) {
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: '@Url.Action("DeleteSensor", "PredefinedViews")',
                data: JSON.stringify({ pviID: PredefineViewsItemID, pID: PredefineViewID }),
                dataType: "json",
                complete: function () {

                    var urlShowSensors = "@Url.Action("ShowSensorNames", "PredefinedViews", new { predefinedViewID = "PredefID" })";
                    urlShowSensors = urlShowSensors.replace("PredefID", PredefineViewID);
                    $(divSensorNames).load(urlShowSensors); //this is the partial view inside the parrent view that I'm updating
                },

            });
        }
    });
});

What happens here is that if the session "LoggedUserID" is expired, what it will do is it will only redirect that div container divSensorNames (where the partial view is) to the login page but leave the entire parrent page stuck where it was. So I end up with a stupid looking site. What I want here of course is for the entire page to redirect to the login Any suggestions or modifications I should make to have my cite function normally? Basically I have all the functionality working without a hitch, except this "small cosmetics problem".

I also have this in my web.config:

<system.web>
<sessionState mode="InProc" timeout="30" />
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<authentication mode="Forms">
  <forms loginUrl="~/Welcome/Login"></forms>
</authentication>

My logout method:

public ActionResult Logout()
    {
        Session.RemoveAll();
        FormsAuthentication.SignOut();
        return RedirectToAction("Login", "Login");
    }

This is what we do to redirect to login page after 10 hours (same value as session expiration time in web.config) of inactivity.

In your Layout.cshtml, add following method:

    $(function () {
        var _redirectTimeout = 10 * 60 * 60 * 1000; // ten hours timeout - test with 10 * 1000 for ten seconds :)
        var _redirectUrl = '@Url.Action("LogOff", "Account")'; // login URL

        var _redirectHandle = null;

        function resetRedirect() {
            if (_redirectHandle) clearTimeout(_redirectHandle);
            _redirectHandle = setTimeout(function () {
                window.location.href = _redirectUrl;
            }, _redirectTimeout);
        }

        $.ajaxSetup({ complete: function () { resetRedirect(); } }); // reset idle redirect when an AJAX request completes

        resetRedirect(); // start idle redirect timer initially.
    });

AccountController.cs

    [AllowAnonymous]
    [Audit]
    public ActionResult LogOff()
    {
        var userName = "Unknown";

        if (HttpContext.User != null && !string.IsNullOrWhiteSpace(HttpContext.User.Identity.Name))
        {
            userName = HttpContext.User.Identity.Name;
        }

        _logger.Log(string.Format("LogOff request received for user : {0}", userName), 
            LogCategory.Information, GetUserIdentifiableString(userName));

        return LogUserOut();
    }

    private ActionResult LogUserOut()
    {
        Session.Abandon();
        _cookieHelper.ClearAllCookies();

        try
        {
            var membershipUser = Membership.GetUser(false);

            _membershipService.SignOut();

            membershipUser.LastActivityDate = DateTime.UtcNow.AddMinutes(-(Membership.UserIsOnlineTimeWindow + 1));
            _membershipService.UpdateUser(membershipUser);
        }
        catch
        {
            _membershipService.SignOut();
        }

        return RedirectToAction("Login", "Account");
    }

NOTE: Above code is for example only, only use what you need in your project.

The code below will only usefull when the user try to reload or try to go some other page in application after the session expires.

Put the below code in your Web.config file

 <system.web>
   <authentication mode="Forms">
     <forms loginUrl="~/Welcome/Login" />
   </authentication>
</system.web>

Note mention the URl of the login page on loginUrl in the above forms tag in you application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM