ajax 当会话过期时,使用 ASP.NET MVC 重定向到登录页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7091498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 11:03:08  来源:igfitidea点击:

With ASP.NET MVC redirect to login page when session expires

ajaxasp.net-mvc

提问by Manjusha Kondapally

I am using ASP.NET MVC. I want to redirect to login page when session expires. How can I achieve this? If I am doing an AJAX call to a method in controller then if my session expires in that situation also I want to redirect to login page.

我正在使用 ASP.NET MVC。我想在会话过期时重定向到登录页面。我怎样才能做到这一点?如果我正在对控制器中的方法进行 AJAX 调用,那么如果我的会话在这种情况下过期,我也想重定向到登录页面。

采纳答案by Felipe Oriani

you could do this by 3 ways:

你可以通过 3 种方式做到这一点:

  1. Create a filter to your actions and apply it programming a code in OnActionExecuting (before the action been executed), http://www.asp.net/mvc/tutorials/understanding-action-filters-cs

  2. Create a base class (inheriting from Controller class) and make your controllers inherits from this one. In this class you could overwrite a method called OnActionExecuting, like the filter.

  3. Don't use Session for Authentication, you can use Forms authentication and keep it simple to use, look this: http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx

  1. 为您的操作创建过滤器并将其应用在 OnActionExecuting 中编写代码(在执行操作之前),http://www.asp.net/mvc/tutorials/understanding-action-filters-cs

  2. 创建一个基类(继承自 Controller 类)并使您的控制器继承自该类。在这个类中,你可以覆盖一个叫做 OnActionExecuting 的方法,比如过滤器。

  3. 不要使用会话进行身份验证,您可以使用表单身份验证并使其易于使用,请看:http: //weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework -using-forms-authentication.aspx

In my opinion, the solution 3 is better than other. I hope it works for you!

在我看来,解决方案 3 比其他方案更好。我希望这个对你有用!

回答by Michael

because it's possible to copy the security-cookie of the Forms-Authentication use it to simulate a registered user I use the following attribute to bind the authentication to the current session lifetime.

因为可以复制 Forms-Authentication 的安全 cookie 使用它来模拟注册用户我使用以下属性将身份验证绑定到当前会话生命周期。

To make the Attribute work you have to set session["user"] = MyUser on login and call session.abandom() on logout. I don't know if the redirect works with ajax calls - that's something you have to try.

要使属性起作用,您必须在登录时设置 session["user"] = MyUser 并在注销时调用 session.abandom()。我不知道重定向是否适用于 ajax 调用 - 这是您必须尝试的事情。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class CheckUserSessionAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        var user = session["User"];

        if (((user == null) && (!session.IsNewSession)) || (session.IsNewSession))
        {
            //send them off to the login page
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Account/LogOff");
            session.RemoveAll();
            session.Clear();
            session.Abandon();
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
    }
}

回答by Alan Macdonald

This answers is heavily based on Michaels except it works ;-)

这个答案很大程度上基于迈克尔斯,但它有效;-)

I changed it to take a delegate for checking if the session has ended so it can work in different apps which might have different ways of determining this and also the login page might be different in other apps. In the Global.asax.cs Application_Start() the code I have in my app is

我将其更改为接受委托以检查会话是否已结束,因此它可以在不同的应用程序中工作,这些应用程序可能具有不同的确定方式,并且登录页面在其他应用程序中也可能不同。在 Global.asax.cs Application_Start() 我的应用程序中的代码是

CheckUserSessionAttribute.CheckSessionAlive = session => (session.GetUser() != null);
CheckUserSessionAttribute.LoginUrl = "~/Account/Login";

Then the attribute class is as follows

那么属性类如下

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class CheckUserSessionAttribute : ActionFilterAttribute
    {
        public static String LoginUrl { get; set; }
        public delegate bool CheckSessionDelegate(HttpSessionStateBase session);

        public static CheckSessionDelegate CheckSessionAlive;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            HttpSessionStateBase session = filterContext.HttpContext.Session;
            if ((CheckSessionAlive == null) || (CheckSessionAlive(session)))
                    return;


            //send them off to the login page
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content(LoginUrl);
            session.RemoveAll();
            session.Clear();
            session.Abandon();

            filterContext.HttpContext.Response.StatusCode = 403;
            filterContext.HttpContext.Response.Redirect(loginUrl, false);
            filterContext.Result = new EmptyResult();

        }
    }

From your controller just add the [CheckUserSession] attribute above the class or the individual actions.

从您的控制器中,只需在类或单个操作上方添加 [CheckUserSession] 属性。

回答by T Gupta

Another plausible solution could be found in here:

另一个合理的解决方案可以在这里找到:

Overriding Controller Methods for session Timeout handling

覆盖会话超时处理的控制器方法