Notify user about session time in asp.net

What is the best way to show a message to a user after a session ends? By then, the user should be logged out and redirected to the start page. I can use javascript to redirect the user to the start page. I just want to show the message on the start page.

+4
source share
4 answers

In your JavaScript redirect, add the request parameter to the redirect URL.

<script> ... // If session is about to timeout... location.href = '/home.aspx?action=expired'; ... </script> 

Then on the start page you can have code to check the query string and display a message if this is an event.

 <% 'home.aspx If Request.QueryString("action") = "expired" Then Response.Write("<p>You have been logged out due to inactivity.</p>") End If %> 
+1
source

The previous version of this answer provides a simple source for resolving a question that no longer exists.

The scenario was that he wanted to be notified before the session timed out so that the action could be taken.

It is not clear if this is an asp.net session or forms authentication ticket, but this is actually the same problem.

Basically this is managing async session state without starting a session / ticket update. A common desire for ajax applications.

The solution is quite simple, but not quite straightforward. There are many problems to solve, but I chose a solution that works reliably for both simple session state and forms authentication.

It consists of a very light httpmodule and an accompanying client script library, and no more than 50 or 60 effective lines of code.

The strategy is to provide an http endpoint that can request the expiration status of a session or form ticket without updating them. The module just sits on the front of the pipeline and serves a couple of β€œvirtual” endpoints with javascript dates and a very simple js lib to make calls.

Demo and source are here: AsynchronousSessionAuditor

Some of you are wondering why I will be worried about this, but probably more of you say hell, yes, what a pain in the patch. I know that in the past I came up with fragile smelly workarounds, and I am very pleased with that.

It can be used in a standard postback application, or rather in an ajax application. Also ... You can learn more about the Http request life cycle here and here . If interested, learn more about using raw xmlhttp for asp.net endpoints here

Abbreviation of the previous spike code. Check the change history if you are interested.

Here are the relevant source files. The full reference implementation is available at the link above ....

HttpModule

 // <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditorModule.cs" company="Sky Sanders"> // This source is a Public Domain Dedication. // http://spikes.codeplex.com // Attribution is appreciated. // </copyright> using System; using System.Web; using System.Web.Security; using System.Web.SessionState; namespace Salient.Web.Security { /// <summary> /// AsynchronousSessionAuditorModule provides a mechanism for auditing the lifecycle /// of an ASP.Net session and/or an ASP.Net FormsAuthentication cookie in the interest /// of providing better monitoring and control of a user session. This is becoming more /// important as more and more web apps are single page apps that may not cycle a page for /// many minutes or hours. /// /// Storing a token in the Asp.net Session was for many years the default authentication strategy. /// The are still valid applications for this techique although FormsAuthentication has far /// surpassed in security and functionality. /// /// What I am providing is a manner in which to transparently monitor the expiration status of each /// by implementing a module that recognizes two virtual endpoints: /// /// http://mysite/.aspnetsession /// http://mysite/.formsauthticket /// /// By making a request to these urls you will be delivered a javascript date in numeric form that /// represents the expiration dateTime of either the current ASP.Net session, if any, or the current /// FormsAuthentication ticket expiration, if any. /// /// If the requested item does not exists, zero is returned. Any value served by this module should /// be cast to a date and compared with Now. If less than you should take action. You should have /// taken action on the client before the session timed out, aided by the output of this module, but /// hey, nobody is perfect. /// </summary> public class AsynchronousSessionAuditorModule : IHttpModule { // note: these must remain in sync with the string keys in the javascript private const string AspSessionAuditKey = ".aspnetsession"; private const string FormsAuthAuditKey = ".formsauthticket"; #region IHttpModule Members public void Init(HttpApplication context) { // this is our audit hook. get the request before anyone else does // and if it is for us handle it and end. no one is the wiser. // otherwise just let it pass... context.BeginRequest += HandleAuditRequest; // this is as early as we can access session. // it is also the latest we can get in, as the script handler is coming // right after and we want to beat the script handler to the request // will have to set a cookie for the next audit request to read in Begin request. // the cookie is used nowhere else. context.PostAcquireRequestState += SetAuditBugs; } public void Dispose() { } #endregion private static void SetAuditBugs(object sender, EventArgs e) { HttpApplication app = (HttpApplication) sender; if ((app.Context.Handler is IRequiresSessionState || app.Context.Handler is IReadOnlySessionState)) { HttpCookie sessionTimeoutCookie = new HttpCookie(AspSessionAuditKey); // check to see if there is a session cookie string cookieHeader = app.Context.Request.Headers["Cookie"]; if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0) && !app.Context.Session.IsNewSession) { // session is live and this is a request so lets ensure the life span app.Context.Session["__________SessionKicker"] = DateTime.Now; sessionTimeoutCookie.Expires = DateTime.Now.AddMinutes(app.Session.Timeout).AddSeconds(2); sessionTimeoutCookie.Value = MilliTimeStamp(sessionTimeoutCookie.Expires).ToString(); } else { // session has timed out; don't fiddle with it sessionTimeoutCookie.Expires = DateTime.Now.AddDays(-30); sessionTimeoutCookie.Value = 0.ToString(); } app.Response.Cookies.Add(sessionTimeoutCookie); } } private static void HandleAuditRequest(object sender, EventArgs e) { HttpContext context = ((HttpApplication) sender).Context; bool formsAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + FormsAuthAuditKey); bool aspSessionAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + AspSessionAuditKey); if (!formsAudit && !aspSessionAudit) { // your are not the droids i am looking for, you may move along... return; } double timeout; // want to know forms auth status if (formsAudit) { HttpCookie formsAuthCookie = context.Request.Cookies[FormsAuthentication.FormsCookieName]; if (formsAuthCookie != null) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsAuthCookie.Value); timeout = MilliTimeStamp(ticket.Expiration); } else { timeout = 0; } } // want to know session status else { // no session here, just take the word of SetAuditBugs HttpCookie sessionTimeoutCookie = context.Request.Cookies[AspSessionAuditKey]; timeout = sessionTimeoutCookie == null ? 0 : Convert.ToDouble(sessionTimeoutCookie.Value); } // ensure that the response is not cached. That would defeat the whole purpose context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1)); context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetNoStore(); // the money shot. a javascript date. context.Response.Write(timeout.ToString()); context.Response.Flush(); context.Response.End(); } /// <summary> /// Found Code: http://forums.asp.net/t/1044408.aspx /// </summary> /// <param name="TheDate"></param> /// <returns></returns> private static double MilliTimeStamp(DateTime TheDate) { DateTime d1 = new DateTime(1970, 1, 1); DateTime d2 = TheDate.ToUniversalTime(); TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks); return ts.TotalMilliseconds; } } } 

Client library

 // <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditor.js" company="Sky Sanders"> // This source is a Public Domain Dedication. // http://spikes.codeplex.com // Attribution is appreciated. // </copyright> var AsynchronousSessionAuditor = { /// this script really should be served as a resource embedded in the assembly of the module /// especially to keep the keys syncronized pollingInterval: 60000, // 60 second polling. Not horrible, except for the server logs. ;) formsAuthAuditKey: ".formsauthticket", // convenience members aspSessionAuditKey: ".aspnetsession", errorCallback: function(key, xhr) { /// <summary> /// Default behavior is to redirect to Default and provide the xhr error status text /// in the loggedout query param. /// /// You may replace this default behaviour with your own handler. /// eg AsynchronousSessionAuditor.errorCallback = myMethod; /// </summary> /// <param name="key" type="String"></param> /// <param name="xhr" type="XMLHttpRequest"></param> window.location = "Default.aspx?loggedout=Error+" + xhr.statusText; }, timeoutCallback: function(key, xhr) { /// <summary> /// Default behavior is to redirect to Default and provide the key value /// in the loggedout query param. /// /// You may replace this default behaviour with your own handler. /// eg AsynchronousSessionAuditor.timeoutCallback= myMethod; /// </summary> /// <param name="key" type="String"></param> /// <param name="xhr" type="XMLHttpRequest"></param> window.location = "Default.aspx?loggedout=" + key; // or just refresh. you will be sent to login.aspx }, statusCallback: function(value) { /// <summary> /// Default behavior is to do nothing, which is not very interesting. /// This value is set when AsynchronousSessionAuditor.init is called /// </summary> /// <param name="value" type="String"> /// The responseText of the audit request. Most certainly is a JavaScript Date /// as a number. Just cast to date to get the requested expiration dateTime. /// eg var exp = new Date(parseFloat(value)); if (isNaN(exp)){this should never happen} /// </param> window.location = "Default.aspx?loggedout=" + key; // or just refresh. you will be sent to login.aspx }, createXHR: function() { /// <summary> /// This xhr factory is not the best I have see. /// You may wish to replace it with another or /// use your favorite ajax library to make the /// call. /// </summary> var xhr; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } else { throw new Error("Could not create XMLHttpRequest object."); } return xhr; }, auditSession: function(key) { /// <summary> /// Make a request that will be serviced by the audit module to determine the /// state of the current FormsAuthentication ticket or Asp.Net session /// /// The return value is a JavaScript date, in numeric form, that represents the /// expiration of the item specified by key. /// Just cast it to date, ie new Date(parseFloat(xhr.resposeText)) /// </summary> /// <param name="key" type="String"> /// the server key for the item to audit. /// /// use ".formsauthticket" to get the expiration dateTime for the forms authentication /// ticket, if any. /// /// use ".aspnetsession" to get the expiration of the current ASP.Net session. /// /// Both have convenience members on this object. /// </param> var xhr = AsynchronousSessionAuditor.createXHR(); xhr.open("GET", key, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status != 200) { AsynchronousSessionAuditor.errorCallback(key, xhr); } else { var timeout = parseFloat(xhr.responseText) if (isNaN(timeout) || (new Date(timeout) < new Date())) { AsynchronousSessionAuditor.timeoutCallback(key, xhr); } else { AsynchronousSessionAuditor.statusCallback(xhr.responseText); } } } }; xhr.send(null); }, init: function(key, statusCallback) { // set the statusCallback member for reference. AsynchronousSessionAuditor.statusCallback = statusCallback; // check right now AsynchronousSessionAuditor.auditSession(key); // and recurring window.setInterval((function() { AsynchronousSessionAuditor.auditSession(key) }), AsynchronousSessionAuditor.pollingInterval); } }; function callScriptMethod(url) { /// <summary> /// /// Simply makes a bogus ScriptService call to a void PageMethod name DoSomething simulating /// an async (Ajax) call. /// This resets the session cookie in the same way a postback or refresh would. /// /// The same would apply to a ScriptService enabled XML Webservice call. /// </summary> var xhr = AsynchronousSessionAuditor.createXHR(); xhr.open("POST", url, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status != 200) { alert("script method call failed:" + xhr.statusText); } } }; xhr.setRequestHeader("content-type", "application/json"); var postData = null; xhr.send(postData); } 

Using

 <script src="AsynchronousSessionAuditor.js" type="text/javascript"></script> <script type="text/javascript"> function reportStatus(value) { /// <summary> /// In a typical session/ticket lifetime you might display a warning at T-5 minutes that the session /// is expiring and require an action. /// </summary> document.getElementById("sessionTimeout").innerHTML = "Session expires in " + parseInt((new Date(parseFloat(value)) - new Date()) / 1000) + " seconds."; } function init() { // default is 60 seconds. Our session is only 1 minute so lets get crazy and poll every second AsynchronousSessionAuditor.pollingInterval = 1000; AsynchronousSessionAuditor.init(AsynchronousSessionAuditor.aspSessionAuditKey, reportStatus); } </script> 
+15
source

Typically, a page will use JavaScript to store a timer and display a popup or dhtml message after a minute or two before the session expires. My bank is doing this.

This is very annoying because if the user has several tabs open for the same site, one tab will know that the session will expire and the other tab will not, so you can get a warning even if it’s incorrect. If you try to use an AJAX call to request a server until the session expires, you just increased the session timeout and actually made the session never expire while the browser window is open (which may not be so bad depending on your particular system tuations).

+2
source

Other answers suggest showing a notification on a page that occasionally .. but I think you are asking how to display a message on the page that the user is redirected to.

One possibility is to simply pass the URL request parameter to the start page only by the session timeout. Then your script or asp.net code may decide to display the message if there is a parameter.

+1
source

Source: https://habr.com/ru/post/1300831/


All Articles