ASP.NET Push Redirect on Session Timeout

Szukam tutoriala, wpisu na blogu lub pomocy w technice stron internetowych, które automatycznie wypychają użytkowników (tj. bez postbacku) po wygaśnięciu sesji. Każda pomoc jest doceniana

Author: Michael, 2009-01-27

10 answers

Zazwyczaj ustawiasz limit czasu sesji, a dodatkowo możesz dodać nagłówek strony, aby automatycznie przekierować bieżącą stronę do strony, na której wyczyścisz sesję tuż przed limitem czasu sesji.

Z http://aspalliance.com/1621_Implementing_a_Session_Timeout_Page_in_ASPNET.2

namespace SessionExpirePage
{
    public partial class Secure : System.Web.UI.MasterPage
    {
        public int SessionLengthMinutes
        {
            get { return Session.Timeout; }
        }
        public string SessionExpireDestinationUrl
        {
            get { return "/SessionExpired.aspx"; }
        }
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.PageHead.Controls.Add(new LiteralControl(
                String.Format("<meta http-equiv='refresh' content='{0};url={1}'>", 
                SessionLengthMinutes*60, SessionExpireDestinationUrl)));
        }
    }
}

SessionExpireDestinationUrl powinien zawierać link do strony, na której wyczyścisz sesję i inne dane użytkownika.

Gdy nagłówek refresh wygaśnie, automatycznie przekieruj ich na tę stronę.

 26
Author: TJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 20:03:42

Tak naprawdę nie możesz" wypchnąć " klienta ze swojej strony. Twoja strona odpowie na prośby klienta, ale to naprawdę wszystko.

Oznacza to, że musisz napisać coś po stronie klienta (Javascript), które określi, kiedy użytkownik przekroczył czas, prawdopodobnie porównując bieżący czas z ostatnim czasem, jaki ma w pliku cookie witryny (który aktualizujesz z bieżącym czasem za każdym razem, gdy użytkownik odwiedza stronę w witrynie), a następnie przekierować, jeśli różnica jest taka sama. większa niż określona kwota.

(zauważam, że niektórzy opowiadają się za stworzeniem skryptu, który przekieruje użytkownika po pewnym czasie na stronę. Będzie to działać w prostym przypadku, ale jeśli użytkownik ma dwa otwarte okna w witrynie i często używa jednego okna,a drugie okno nie-tak-bardzo, to nie-tak-bardzo nagle przekieruje użytkownika na stronę przekierowującą, mimo że użytkownik był stale na stronie. Dodatkowo, nie jest naprawdę zsynchronizowany z każdą sesją wykonywaną po stronie serwera. Z drugiej strony, z pewnością łatwiej jest kodować, a jeśli to wystarczy, to świetnie!)

 10
Author: Beska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 20:07:47

W sekcji użyj znacznika odświeżania META w następujący sposób:

<meta http-equiv="refresh" content="0000; URL=target_page.html">

Gdzie 0000 to limit czasu sesji w sekundach i target_page.html adres strony do przekierowania.

 6
Author: devio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 20:03:03

Używając niestandardowej klasy Page i Javascript również możemy to osiągnąć.

Utwórz niestandardową klasę pagebase i zapisz wspólne kody funkcjonalności do tej klasy. Dzięki tej klasie możemy udostępniać wspólne funkcje innym stronom internetowym. W tej klasie potrzebujemy dziedziczyć system .Www.UI.Strona Klasa. Umieść poniższy kod w klasie Pagebase

baza stron.cs

namespace AutoRedirect
{
    public class PageBase : System.Web.UI.Page
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            AutoRedirect();
        }

        public void AutoRedirect()
        {
            int int_MilliSecondsTimeOut = (this.Session.Timeout * 60000);
            string str_Script = @"
               <script type='text/javascript'> 
                   intervalset = window.setInterval('Redirect()'," +
                       int_MilliSecondsTimeOut.ToString() + @");
                   function Redirect()
                   {
                       window.location.href='/login.aspx'; 
                   }
               </script>";

           ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", str_Script);
        }
    }
}

Powyżej Funkcja AutoRedirect zostanie użyta do przekierowania strony logowania gdy sesja wygaśnie, używając okna javascript.setInterval , to okno.setInterval wykonuje funkcję javascript wielokrotnie z określonym opóźnieniem czasowym. Tutaj konfigurujemy opóźnienie czasowe jako wartość limitu czasu sesji. Po osiągnięciu czasu wygaśnięcia sesji automatycznie wykonuje funkcję przekierowania i kontroluje transfer do logowania strona.

OriginalPage.aspx.cs

namespace appStore
{
    public partial class OriginalPage: Basepage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }     
    }
}

OriginalPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OriginalPage.aspx.cs" Inherits="AutoRedirect.OriginalPage" %>

www.config

<system.web>    
    <sessionState mode="InProc" timeout="3"></sessionState>
</system.web>

Uwaga: Zaletą korzystania z Javascript jest to, że możesz wyświetlić niestandardową wiadomość w polu alert przed lokalizacją.href, który będzie miał doskonały sens dla użytkownika. W przypadku, gdy nie chcesz używać Javascript, możesz wybrać również przekierowanie meta

public void AutoRedirect()
{
    this.Header.Controls.Add(new LiteralControl(
        String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
            this.Session.Timeout * 60, "login.aspx")));
}
 3
Author: Durai Amuthan.H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 06:30:35

Używam MVC3 ASp.net jako początkujący próbowałem wielu rozwiązań, aby rozwiązać mój problem z sesją ( ponieważ używam zmiennej sesji w moim kodzie, a po przekroczeniu limitu czasu nie miałem wartości sesji, podczas gdy wciąż go używam i po prostu okazało się, że mój problem był w pliku konfiguracyjnym. limit czasu między uwierzytelnianiem a sessionState powinien być tak bliski. więc zabiły (puste) w tym samym czasie / / dodaj timeout 1 i 2 do testowania.. powinno być co najmniej 29 i 30

Używałem innych sposób to też działa:

Zaczynając od:

    protected void Session_Start(object src, EventArgs e)
    {
        if (Context.Session != null)
        {
            if (Context.Session.IsNewSession)//|| Context.Session.Count==0)
            {
                string sCookieHeader = Request.Headers["Cookie"];
                if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    //if (Request.IsAuthenticated)
                     FormsAuthentication.SignOut();
                     Response.Redirect("/Account/LogOn");
                }
            }
        }

    }

    protected void Session_End(object sender, EventArgs e)
    {
     //Code that runs when a session ends. 
     //Note: The Session_End event is raised only when the sessionstate mode 
     //is set to InProc in the Web.config file. If session mode is set to StateServer
      //or SQLServer, the event is not raised. 
        Session.Clear();          
    }

I:

public class SessionExpireFilterAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext ctx = HttpContext.Current;

        // check if session is supported
        if (ctx.Session != null)
        {

            // check if a new session id was generated
            if (ctx.Session.IsNewSession)
            {
                // If it says it is a new session, but an existing cookie exists, then it must
                // have timed out
                string sessionCookie = ctx.Request.Headers["Cookie"];
                if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    ctx.Response.Redirect("~/Home/LogOn");
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

I nawet pracował z Ajaxem, aby rozwiązać session issuse:

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Session.Count == 0 || Session["CouncilID"] == null)
            Response.Redirect("/Account/LogOn");

        if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
        {
            filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthorizeUserAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAjaxRequest())
            {//validate http request.
                if (!httpContext.Request.IsAuthenticated
                    || httpContext.Session["User"] == null)
                {
                    FormsAuthentication.SignOut();
                    httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
                    return false;
                }
            }
            return true;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult
                {
                    Data = new
                    {
                        // put whatever data you want which will be sent
                        // to the client
                        message = "sorry, but you were logged out"
                    },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }

    }
 2
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 14:34:05

Po prostu skopiuj i wklej ten fragment kodu w swojej sieci.Plik konfiguracyjny:

<authentication mode="Forms">
  <forms loginUrl="~/Login.aspx" slidingExpiration="true" timeout="29" />
</authentication>

<sessionState timeout="30" mode="InProc" cookieless="false" />

Możesz umieścić tę linię na swojej stronie.Mistrz:

Response.AppendHeader("Refresh", 
                      Convert.ToString((Session.Timeout * 60)) + 
                      ";URL=~/Login.aspx");
 2
Author: ersegun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-04 15:17:36

Niestety nie da się tego zrobić. Limit czasu sesji występuje tylko po stronie serwera i nie zostanie wykryty, dopóki użytkownik nie wykona jakiejś akcji post back.

Możesz jednak wprowadzić kod HTML lub JavaScript, który automatycznie przesunie użytkownika na stronę wylogowania w tym samym czasie, co limit czasu sesji. Nie gwarantuje to idealnej synchronizacji i mogą wystąpić problemy, jeśli użytkownik wykonuje elementy wymagające czasu, a ty nie Resetowanie zegara.

Zazwyczaj dodaję ten kod do moich zdarzeń Page_Load, aby to osiągnąć.

' Register Javascript timeout event to redirect to the login page after inactivity
  Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", _
                                              "setTimeout(""top.location.href = 'Login.aspx'""," & _
                                               ConfigurationManager.AppSettings("SessionTimeoutMilliseconds") & ");", True)
 1
Author: Dillie-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 20:01:24

I jeśli użyjesz następującego kontrolera logowania, wyśle cię na żądany adres URL przed zalogowaniem:

   [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {

                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                {
                    //return Redirect(returnUrl);
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                      return RedirectToAction("Index", "Home");
                    }

                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }
 1
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 14:41:37

Oczywiście musisz użyć [Authorize] nad klasą kontrolera lub nawet akcją w specific.

[Authorize]
public class MailController : Controller
{
}
 1
Author: Rasha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 20:04:53

Cóż, robi się to trudne dla żądań Ajaxu, jak zauważył Zhaph - Ben Duguid. Oto moje rozwiązanie, aby to działało z AJAX (za pomocą kontrolek Telerik web, ale są one zbudowane przy użyciu ASP.NET AJAX toolkit I believe).

W skrócie, zwijałem swoją własną sesję przesuwania wydechu.

Na mojej stronie.Master, aktualizuję zmienną sesji na każdym postback (żądanie postback lub AJAX, ponieważ żądania AJAX nadal uruchamiają Zdarzenie Page_Load):
protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            if (this.Request.IsAuthenticated)
                this.pnlSessionKeepAlive.Visible = true;
            else
                this.pnlSessionKeepAlive.Visible = false;
        }

        if (this.Session["SessionStartDateTime"] != null)
            this.Session["SessionStartDateTime"] = DateTime.Now;
        else
            this.Session.Add("SessionStartDateTime", DateTime.Now);
    }

Wtedy w moim znaczniki dla mojej strony.Mistrzu, dodałem iframe ze stroną ASPX używam "za kulisami", aby sprawdzić i sprawdzić, czy mój Niestandardowy przesuwny termin ważności wygasł:

<asp:Panel runat="server" ID="pnlSessionKeepAlive" Visible="false">
 <iframe id="frame1" runat="server" src="../SessionExpire.aspx" frameborder="0" width="0" height="0" / >
 </asp:Panel>
Teraz w mojej sesji.strona aspx, po prostu odświeżam stronę co jakiś czas i sprawdzam czy timestamp wygasł, a jeśli tak, to Przekierowuję do wylogowania.strona aspx, która następnie określa, na którą stronę logowania ma odesłać użytkownika:
public partial class SessionExpire : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        /* We have to do all of this because we need to redirect to 2 different login pages. The default .NET
         * implementation does not allow us to specify which page to redirect expired sessions, its a fixed value.
         */
        if (this.Session["SessionStartDateTime"] != null)
        {
            DateTime StartTime = new DateTime();
            bool IsValid = DateTime.TryParse(this.Session["SessionStartDateTime"].ToString(), out StartTime);
            if (IsValid)
            {
                int MaxSessionTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionKeepAliveMins"]);
                IsValid = (DateTime.Now.Subtract(StartTime).TotalMinutes < MaxSessionTimeout);
            }

            // either their session expired or their sliding session timeout has expired. Now log them out and redirect to the correct
            // login page.
            if (!IsValid)
                this.Logout();
        }
        else
            this.Logout();

        // check every 60 seconds to see if the session has expired yet.
        Response.AddHeader("Refresh", Convert.ToString(60));
    }

    private void Logout()
    {
        this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "TimeoutScript",
                    "setTimeout(\"top.location.href = '../Public/Logout.aspx'\",\"1000\");", true);
    }
}

Wielkie dzięki dla osób powyżej, którzy opublikowali informacje, to doprowadziło mnie do mojego rozwiązania i mam nadzieję, że to pomaga innym.

 0
Author: Chris Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-03 00:49:53