Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent Ajax calls from keeping a session alive?

I'm using cookie authentication in MVC5. My web pages rely heavily on authenticated as well as unauthenticated Ajax calls every 1-5 seconds to keep data updated. Consequently, my users never log out of the site.

My ideal scenario: If a user is actively browsing or conducting actions on my site, keep the session alive. If they have left a page open after 10 minutes, I'd like their session to timeout and I’'ll use the failing Ajax calls to redirect to a login page. I think this would best be accomplished at the controller or action level.

I tried controlling the session state behavior as suggested below but the session still did not time out. After 65 seconds of hitting ReadOnly/Public once per second, I call ReadOnly/Authorized and successfully retrieve data from it.

Here is my CookieAuthentication configuration.

public void ConfigureAuth(IAppBuilder app)
{
    // Enable the application to use a cookie to store information for the signed in user
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        ExpireTimeSpan = TimeSpan.FromMinutes(1),
    });
}

My test page:

<div id="public"></div>
<div id="authorized"></div>


@section scripts{
<script>

function poll(times) {
    var url = '/ReadOnly/Public';
    $.ajax({
        url: url,
        dataType: 'json',
        data: null,
        cache: false,
        success: function (data) {
            $('#public').html(times + ' ' + data.test);

        },
        error: function (data) {
            $('#public').html(times + ' ' + 'failed');
        }
    });
};

function checkAuth(times) {
    var url = '/ReadOnly/Authorized';
    $.ajax({
        url: url,
        dataType: 'json',
        data: null,
        cache: false,
        success: function (data) {
            $('#authorized').html(times + ' ' + data.test);

        },
        error: function (data) {
            $('#authorized').html(times + ' ' + 'failed');
        }
    });
};

$(function () {
    var times = 1;
    setInterval(function () {
        poll(times);
        times++;
    }, 1000);
    setInterval(function () {
        checkAuth(times);
    }, 65000);

});
</script>
}

and test controller code (tried this with both the disabled and readonly options)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.SessionState;

namespace SessionTest.Controllers
{
[SessionState(SessionStateBehavior.ReadOnly)]
public class ReadOnlyController : Controller
{
    [Authorize]
    public ActionResult Authorized()
    {
        return Json(new
        {
            test = "ReadOnly and Authorized"
        }, JsonRequestBehavior.AllowGet);
    }

    public ActionResult Public()
    {
        return Json(new
        {
            test = "ReadOnly and Public"
        }, JsonRequestBehavior.AllowGet);
    }
}
}
like image 983
Bill Shihara Avatar asked May 04 '14 17:05

Bill Shihara


3 Answers

Maybe you need to have 2 separate web apps. One is for serving authenticated requests. Another one is for all public requests.

That's similar to how the Google Analytics script creates and maintains its own Session on Google side about your site without impacting your web application's internal session management. Otherwise, you will get stuck with the default behavior of ASP .NET the way it is handling cookies and keeps session alive.

Good luck.

like image 53
Believe2014 Avatar answered Nov 13 '22 12:11

Believe2014


I wouldn't implement a timeout in this situation. In fact I try to avoid them unless there is a fundamental and key reason why they are necessary, otherwise they just become an annoyance.

However if you do feel you need one, I would implement it in this case, by creating a separate javascript function which has a timer, and that is reset with user input. If the timer completes an ajax call is performed that executes a manual session invalidation on server side.

like image 43
NimChimpsky Avatar answered Nov 13 '22 13:11

NimChimpsky


I would configure the listener method or class to not use session which will prevent it from being extended.

There are attributes available for both methods and controllers that provides different session modes.

More info here: http://www.dotnet-tricks.com/Tutorial/mvc/906b060113-Controlling-Session-Behavior-in-Asp.Net-MVC4.html

like image 39
Christian Landgren Avatar answered Nov 13 '22 13:11

Christian Landgren