David G

David G

  • 1.4k
  • 224
  • 13.9k

MVC Sessions extending timeout time w/o losing sessions vars

May 25 2017 9:51 AM

Oh the wonderful MVC world....

I am trying to setup a timeout script for my website. Currently it seems to work but if the user wanted to extend the timeout time then move to another page it seems to have lost all of my session varibles I had saved.

FilterConfig.cs code:
  1. public class IsAuthenticatedAttribute : ActionFilterAttribute  
  2.     {  
  3.         public override void OnActionExecuting(ActionExecutingContext filterContext)  
  4.         {  
  5.             if (rowCnt >= 1) //Making sure user has permissions to even view this site  
  6.             {  
  7.                 System.Diagnostics.Debug.WriteLine("Current timeout: " + HttpContext.Current.Session.Timeout);  
  8.                 System.Diagnostics.Debug.WriteLine("Session timeout: " + HttpContext.Current.Session["timeoutDate"]);  
  9.   
  10.                 if (HttpContext.Current.Session.Timeout == 20) //20 is the default timeout setting  
  11.                 {  
  12.                     //It's the first time the user has visited the page so set timeout!  
  13.                     filterContext.HttpContext.Session.Clear();  
  14.                     filterContext.HttpContext.Session.RemoveAll();  
  15.   
  16.                     HttpContext.Current.Session.Timeout = 1;  
  17.                     HttpContext.Current.Session["sessionVars"] = new initSessionVars().getSVars;  
  18.                     sessionVars sVars = HttpContext.Current.Session["sessionVars"as sessionVars;  
  19.   
  20.                     //Send them to the main page in order to populate the sessions and needed data  
  21.                     filterContext.Result = new RedirectResult("/");   
  22.                 } else  
  23.                 {  
  24.                     if (HttpContext.Current.Session["timeoutDate"] == null)  
  25.                     {  
  26.                         //No timeout has been saved so save it  
  27.                         int sessionTimeout = HttpContext.Current.Session.Timeout;  
  28.   
  29.                         HttpContext.Current.Session["timeoutDate"] = DateTime.Now.AddMinutes(sessionTimeout);  
  30.                     }  
  31.                 }                  
  32.             } else  
  33.             {  
  34.                 //User was not found so they are NOT good to go!  
  35.                 filterContext.HttpContext.Response.Redirect("~/Account/Unauthorized");  
  36.             }  
  37.         }  
  38.     }  
 

I am using some jQuery in order to check for the timeout and present the user with a message box 10 seconds before it resets the session and sends them to a "sessions over" page.

_Layout.cshtml code:

  1. var idleTime = 0;  
  2.  var secondsLeft = 10;  
  3.  var sTimer;  
  4.  var idleInterval;  
  5.   
  6.     $(document).ready(function () {  
  7.         idleInterval = setInterval(timerIncrement, @Html.Raw((Session.Timeout * 60) * 1000));  
  8.   
  9.         $(".sleepy-close, .sleepy-wake-up").click(function () {  
  10.             $(".sleepy-overlay").fadeOut('fast');  
  11.             clearInterval(sTimer);  
  12.             idleTime = 0;  
  13.   
  14.             $.ajax({  
  15.                 url: 'Home/sessionChk',  
  16.                 type: 'POST',  
  17.                 cache: false,  
  18.                 dataType: 'json',  
  19.                 data: {  
  20.                     continueSession: true  
  21.                 },  
  22.                 success: function (responce) {  
  23.                     console.log('done');  
  24.                     idleInterval = setInterval(timerIncrement, responce);  
  25.                     setVars();  
  26.                 },  
  27.                 error: function (responce) {  
  28.                     showNotify('error''An error of<br/>' + responce + '<br/>Has occurred. Please get in touch with me about this error.', 20000);  
  29.                 }  
  30.             });  
  31.         });  
  32.   
  33.         $('.sleepy-modal').click(function (event) {  
  34.             event.stopPropagation();  
  35.         });  
  36.     });  
  37.   
  38.     function setVars() {  
  39.         idleTime = 0;  
  40.         secondsLeft = 10;  
  41.         $('#timer').html(secondsLeft);  
  42.     }  
  43.   
  44.     function timerIncrement() {  
  45.         idleTime++;  
  46.   
  47.         if (idleTime > 1) {  
  48.             $('.sleepy-overlay').fadeIn('slow');  
  49.             clearInterval(idleInterval);  
  50.             sessionTimer();  
  51.         }  
  52.     }  
  53.   
  54.     function sessionTimer() {  
  55.         sTimer = setInterval(function () {  
  56.             $('#timer').html(secondsLeft);  
  57.             secondsLeft--;  
  58.   
  59.             if (secondsLeft <= 0) {  
  60.                 clearInterval(sTimer);  
  61.   
  62.                 $.ajax({  
  63.                     url: 'Home/sessionChk',  
  64.                     type: 'POST',  
  65.                     cache: false,  
  66.                     dataType: 'json',  
  67.                     data: {  
  68.                         continueSession: false  
  69.                     },  
  70.                     success: function (responce) {  
  71.                         //clear the full screen for user to input new data  
  72.                         console.log('done');  
  73.                     },  
  74.                     error: function (responce) {  
  75.                         showNotify('error''An error of<br/>' + responce + '<br/>Has occurred. Please get in touch with me about this error.', 20000);  
  76.                     }  
  77.                 });  
  78.             }  
  79.         }, 1000);  
  80.     }  

If the user clicks the "stay awake" button then it sends an AJAX request to Home/sessionChk which sends a true for the continueSession.

HomeController.cs sessionChk code:

  1. public class HomeController : Controller  
  2. {   
  3.    [HttpPost]  
  4.    public void sessionChk(bool continueSession)  
  5.    {  
  6.        ActionExecutingContext filterContext = new ActionExecutingContext();  
  7.   
  8.        if (continueSession)  
  9.        {  
  10.            //Add more time to the session timeout  
  11.            HttpContext.Session.Timeout = 31;  
  12.        }  
  13.        else  
  14.        {  
  15.            //Lets go to the sessions exspiered page  
  16.            filterContext.Result = new RedirectResult("/");  
  17.        }  
  18.    }  
  19. }  

So after it adds 31 more mintues I go ahead and pick another page within the site to visit. Once that page starts loading it tells me a session varible I am trying to load is no longer there.....

During the 1 minute the session starts when the page loads for the first time I can surf to any page within the site and all the sessions are fine and load up with the correct data so I know they have data at the beginning.

So what am I doing incorrectly since it doesnt seem to safe the session data when I extend the timeout time?