What is it?
The Heartbeat control that I'm currently developing is a client-side/server-side solution which displays a popup modal to the user after 27 minutes of server session inactivity thereby displaying a countdown of 3 minutes before the session expires and returns the user to the Login page. The modal popup also includes an "Extend time" button and a "Logout" button.
How it works
On the client-side, once the page loads the heartbeat control is initialized and the countdown starts. The heartbeat control has a MaxHealth (milliseconds) and a CriticalHealthRatio (percentage) specifying the session life and when the modal should pop-up respectively.
If the user does nothing during the countdown or alternatively clicks "Logout" then the JavaScript code will redirect the user to the Logout page which clears all sessions and redirects to the Login page.
If the user clicks "Extend time" then an ajax call is made to a web service which simply revitalizes the session on the server-side as well as the client-side's MaxHealth.
Extending control to be multi-tab compatible
At this point, the heartbeat control works on a page by page basis, but does not take into account other tabs that are opened.
Scenario 1: A user logs in and after 15 minutes they open a second tab. Opening another tab will revitalize the session, but the to the first tab the heartbeat is still counting down from that initial MaxHealth, not knowing that the session was in fact reset. Even if the user continues to navigate with the second tab, constantly revitalizing the session, the moment the first tab reaches 0, it will automatically cause the user to be logged out.
Partial Solution
In order to solve the underlying problem of causing the user to be logged out on currently opened tabs which aren't being refreshed, my solution was to implement another web service called GetLastResponse() that retrieves a session which contains a DateTime value of the last server response time.
Therefore on each page request, the server resets the LastReponse session to the current time which is handled in the Global.asax and the HeartBeat control will now countdown from that LastResponse time when the page is loaded on the client-side.
With this new web service which returns the LastResponse time, I can now simply have the heartbeat control on every tab call it every X minutes to determine if the session is any different since the last request thereby synchronizing the Heartbeat controls on all tabs to display the popup at the same time as well as remove the popup on all tabs when the user extends the time on one of the tabs.
But of course, this can't possibly work. The moment I call GetLastResponse() the session is effectively reset in the Global.asax.
Even if I add a condition in the Global.asax which doesn't reset the LastResponse session when a request is made to the GetLastResponse() web service, that doesn't stop the actual session lifetime from being revitalized; it only disassociates the LastResponse DateTime from the actual lifetime of the session.
Questions
I believe the proposed solution will work, however being that the LastResponse
and the actual session lifetime will effectively be different, is
there a better way to go on about this while retaining the core
functionality intended of the Heartbeat control (synchronized
countdown, multi-tab extend time, multi-tab logout)?
Is there a way to designate a web service to not reset the session
lifetime when called but also allows C# to access the session?
Is there a way to request the remaining session lifetime without
revitalizing it?
Related
I have got an Asp.Net MVC application. This is just an approach so I can't provide code.
Basically what I want to achieve is if the session is over show an alert on whatever page the user is on.
The picture from Azure shows what I want to achieve (but this is farther, I want to start with displaying an alert first).
So is there a function or anything provided by asp.net detecting if the session is over? And secondly how would I display an alert?
Unfortunately, there is no easy answer to this. The reason is that if you were to ping the server to check the session, that action would actually renew the session timeout, unless you configure the service to not access the session - which means you need yet another tracking mechanism. The "fake" way is to set a JavaScript time that equals the session timeout. You would need to reset that timer on any ajax call.
The more involved solution is to use a persistent connection technology like SignalR that notifies a subscriber on session_timeout.
There is no specific function in asp.net that notifies the user that the session is over or going to end. But this functionality is seen nowadays in many websites.
The session is started by the server when a postback request is received. When there is no user action for a specific period of time, session expires. You can use javascript alert to show popup to the user regarding session timeout.
I will suggest 2 ways :
Run a timer in client side and notify the user when it is about to expire. For eg. if your session timeout is 5 min, you can probably
notify the user after 4 min that the session will expire in 1 min if
no action is done.
The second approach is to initiate a post-back request to the controller automatically or when user clicks ok button on an
alert(Your session will expire soon and you will be logged out. Do you
wish to extend the session?)
I have a problem with server-side auto-redirection to a login page upon cookie timeout.
Our application uses a wrapper page (called "Application.aspx") which hold all our controls, as well as the rest of our application inside IFrames.
My problem occurs when the Login Cookie times out. The user should be looking at a Timeout warning screen in the form of a RadWindow launched when their user-set lock time is reached. This screen exists until the global Authentication cookie expires. However, at that point, any action redirects only the RadWindow to the login, not the full application.
I have tried implementing a Response.Redirect("SessionTimeout.aspx,false); line to the globabl.aspx page in the AuthenticationRequest event. However, it appears somewhere along the line an Auto control is redirecting before my SessionTimeout page can execute its pageLoad.
Sadly, this is for a large company and I cannot share much exact code, but if anyone has found a way around this I would be very happy.
If anyone else finds this and needs the answer, I ended up creating a new cookie containing the expiry date of the original cookie.
I then checked if the current datetime was close to the value of the exp with jscript at regular intervals, and when it was within 30 seconds of expiring, redirected the user client-side.
Currently, when the using is logged in (using the built in forms authentication) and they let their session timeout, they loose all data when they submit a form. How do I make it so that the viewstate data is resubmitted AFTER logging back in? Example, if they were writing an email and it expires, how do I make it send after they relogin instead of loosing all their data? I don't want a solution that extends the session on these pages please.
viewstate will only work in postback-scenarios,you will lose it if you redirect.So i think you use session for your problem.
I agree with Shree..
You could use a timer of sorts and either do a save to the DB, Session, or Cookie w/ the temp date entered so far.
Also, what I have done on some applications, is before the session will time out give the user a warning popup to "Continue" the session. This takes a little more work..
If you want to preserve the state of the form along with all form data, you don't want automatic redirects to the login page, which means that you need some sort of an "in place" authentication. You may consider intercepting the postback, i.e. adding your own handler to the form submit event, and issuing an AJAX callback to check your session state. If the session is valid, just proceed with the postback, otherwise display a login page in a popup or a modal dialog. The user will be able to resubmit the form after logging in.
I think your problem is not on ViewState, simple solution is save the email and action into local storage[HTML5], when user re-logs on, check the previous action and email, then you can submit email automatically. All browsers except IE6/7 already support local storage now.
I am using a Master page and many other pages from different folders are displayed in the IFrame within the master page.
If the user is not doing anything for some time [5 minutes or so] in any of the other pages, I want to give an alert message either to continue or to log out.
How to do this?
For example setTimout in jsvascript on mouseover for your iFrame. On each mouseover drop your timeout with clearTimeout and create new one.
But I don't think it's a good idea. Better to handle session timeout on the server. More info about sessions state you can find here: ASP.NET Session State
After session ending user might me autmatically logged of and will be requested to login next time on any action whitch post request to the server.
I have a user complaining about frequent timeouts in my Intranet web page. While looking for a solution I found this post:
http://forums.asp.net/t/152925.aspx?PageIndex=1
Where a poster recommends intercepting the redirect to the login page, submit the data to the database, then either reauthorize the user (without their knowledge) or redirect to login page. My goal is to avoid the situation where a user enters data in a form, walks away, then comes back to submit it, only to be told they have to login again (which is fine, if the data remained and the user was sent right back to the original webform).
Does anyone know how I can accomplish this on specific pages in my app (not all of them)?
It's not necessarily trivial, but you can add an ajax component that makes occasional calls to a page to keep the session alive. This way you could lengthen the session for any particular page you need to without affecting the application as a whole.
EDIT
If you really want to let the session expire, but keep the form data, you can implement
protected void Application_PostAuthenticateRequest (object sender, EventArgs e)
event handler in your global.asax.cs file. This is called before the forms authentication redirect happens, and the form data is available to your application at this point, so you can persist it to whatever medium is necessary until your user is authenticated again. In addition, if you check the
((HttpApplication)sender).Request.Path
property it will tell you which page was requested.
Well, the easy way it to drastically lengthen the timeout specified in the web.config file.
I'm going to try using cookies to preserve the data. My plan is to update the user's cookie after each control is changed, then add logic to the page_load property of the page to populate the form data after the user is logged back in.