简体   繁体   中英

ASP.NET MVC & Angular: Custom Attribute / ActionFilter when Session Cookies expire, want it to redirect to Login page but it doesn't always work

Details

I'm using ASP.NET MVC with Angular. If I do a hard refresh (F5), it hits the attribute I created just fine.. also when the session cookies exist it accesses it fine. but say the user is on a certain page, and the session cookie expires while he's on it.. the code will still access my Angular code, but once it's supposed to hit my Controller or probably my Attribute first.. it doesn't. So nothing works on the webpage at that point and nor does it redirect to the Login screen.

I googled around and searched this website as well but haven't found anything that works.. Any help?

My Code

Attribute for all my Controllers EXCEPT by AccountController (it causes a Redirect loop for some reason??). I put this at the top of all my controllers.

[CustomFilters.VerifySession]

My Custom Attribute

public class CustomFilters
{
    public class VerifySessionAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var userId = filterContext.HttpContext.Session["UserId"];
            var userName = filterContext.HttpContext.Session["UserName"];

            if (userId == null || userName == null)
                filterContext.Result = new RedirectResult(string.Format("/Account/Login"));
        }
    }
}

My Login Function

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
    ...
    Session["UserId"] = UserId;
    Session["UserName"] = sql.UserProfiles.Where(c => c.UserId == UserId).Select(x => x.UserName).FirstOrDefault();
    ...
}

Web.config

<system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="1" />  //set to 1 just for testing purposes
    </authentication>
    <sessionState timeout="1" />  //set to 1 just for testing purposes
</system.web>

Not quite enough detail to figure out what's happening, so a couple thoughts:

First, the forms authentication module will redirect before an unauthenticated request hits your filters or controllers. Way it works is the forms module will intercept any 401 Unauthenticated responses generated anywhere in the application and replace them with 302 redirects to the login page.

Second, these redirects won't work on an ajax request. You didn't mention if you checked the responses in your browsers' dev tools, but if you send an ajax request with an expired cookie, the browser will automatically follow the redirect issued by the forms module but won't actually redirect the user to the login page--instead you'll simply get the HTML of the login page as response data in the ajax request.

So it sounds to me like the problem you are having is that the forms module is redirecting unauthenticated requests to the login page, but this just doesn't work for ajax requests made by the angular framework.

Basically what you need is some javascript code to recognize when it's getting an unauthenticated response and actually redirect the page to the login page instead of parsing the response. My own solution (not using angular) was to simply disable the 302 redirect on unauthenticated requests, then instead have javascript handle 401 responses: Best way to handle unauthenticated request in asp.net Web Api

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