views:

2448

answers:

4

I am placing user data in the session then passing it to viewdata to view on a page. Now when my user walks away from his computer for a while, the session ends and the data he entered is lost.(that is ok) The problem is that when he returns he refreshes the screen my page is still showing but all the data is gone. So,

How can I redirect the user to a login screen when the session expires (so he doesnt see a blank page) or I would like to redirect him to a page that states "You have been logged out due to inactivity".

Thanks

+5  A: 

I use some Javascript in my MasterPage to redirect the user (after a prompt to renew the session) to the logout action. It uses an AJAX request back to the Home page of the app to refresh the server side session window when the user clicks the button in the dialog to extend the session. Relies on jQuery and jQuery UI for the dialog.

 <% if (this.Request.IsAuthenticated)
    {
        int sessionDialogWait = 2 * 60 * 1000 - 60 * 500; // ms = 1.5 minutes
        int sessionTimeout = 28 * 60 * 1000; // ms = 28 minutes
        if (ViewData["sessionTimeout"] != null)
        {
            sessionTimeout = ((int)ViewData["sessionTimeout"] * 60 - 120) * 1000;
        }
%>  
<script type="text/javascript">
    var logoutTimer = null;
    var sessionTimer = null;
    var sessionTimeout = Number('<%= sessionTimeout %>');
    var sessionDialogWait = Number('<%= sessionDialogWait %>');

    $(document).ready( function() {
        $('#sessionEndDialog').dialog( {
            autoOpen: false,
            bgiframe: true,
            modal: true,
            buttons: {
                OK: function() {
                    $(this).dialog('close');
                    $.get( '<%= Url.Action( "About", "Home" ) %>', scheduleSessionPrompt, 'html' );
                },
                Logout: logoutOnSessionExpires
            }
        }).ajaxStart( function() { scheduleSessionPrompt(); } );
        scheduleSessionPrompt();
    });

    function scheduleSessionPrompt()
    {
        if (logoutTimer) clearTimeout(logoutTimer);
        if (sessionTimer) clearTimeout(sessionTimer);

        sessionTimer = setTimeout( sessionExpiring, sessionTimeout  );
    }

    function sessionExpiring()
    {
         logoutTimer = setTimeout( logoutOnSessionExpires, sessionDialogWait );
         $('#sessionEndDialog').dialog('open');
    }

    function logoutOnSessionExpires()
    {
        window.location.href = '<%= Url.Action( "Logout", "Account" ) %>';
    }       

    </script>
<% } %>

<div id="sessionEndDialog" title="Session Expiring" style="display: none;">
    <p>Your session is about to expire.  Click OK to renew your session or Logout to logout of the application.</p>
</div>
tvanfosson
Can the Session_End in Global.asax be used to to this?
Tony Borf
I don't see how you would redirect the browser to a different page from the Session_End event unless the browser was periodically checking to see if the session is alive. Unfortunately, having the browser do this will artificially keep the session alive since it will be updated on every query. I'm working on turning this into a jQuery plugin.
tvanfosson
Correct me if I am wrong but Session_End runs in a background thread and as such cannot communicate with the user.love your work tvanfosson, your approach works very well
CodeKiwi
+4  A: 

I'm assuming you're authenticating the user in some way, but are you using Forms Authentication?:

ASP.Net MVC Framework - Using Forms Authentication

If you're already using Forms Authentication, you need to make sure that the authentication cookie expiration time is just a bit shorter than your Session timout.

Kev
Yes, I am using the default MVC project as my base.
Tony Borf
A: 

The data could be still on the page because the browser is caching it.

Try throwing this in and see if the data is still there after the session is dead:

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
ajma
+1  A: 

I had that same problem with an old ASP.net app. The session expires but the user is still authenticated because session and authentication cookies are different and not necessarily they expire at the same time. What I did back then was use the global.asax Session_Start to check if the user was authenticated and log him out.

 protected void Session_Start(Object sender, EventArgs e)
 {
  if (User.Identity.IsAuthenticated)
  {
   FormsAuthentication.SignOut();
   Response.Redirect("~/SessionEnd.aspx");
  }
 }

This forces a user starting a session to login again. You may also use this event to recover session info from the database, or maybe redirecto him to another page but keep his credentials valid.

Ariel Popovsky
Is the session timeout a function of the webserver? (IIS6) Can it only be changed from there in the control panel?
Tony Borf
I tried this code, it loged me out but the Response.Redirect didn't take me to my page.
Tony Borf
You can change Session expiration on your web.config<sessionState mode="InProc" timeout="100"/>or programmatically using Session.Timeout = x;if you sign out you can only go to the login page or a page that is not protected by Authentication.
Ariel Popovsky