Use jQuery to check if ASP.NET Session variable has expired

I have a standard ASP.NET site with standard ASP.NET authentication using Session Variables. Before my javascript does an ajax call, I want to check if the Session variable still exists or whether it has timed out or not. If it does not exist (timed out), redirect the entire window to login.aspx. I am hoping that jQuery has access to the cookies folder storing the ASP.NET Session variable that is supposed to be there, so that it can confirm that it is.
LVL 9
BobHavertyComhAsked:
Who is Participating?
 
Duy PhamFreelance IT ConsultantCommented:
Following your idea of detecting timeout by checking if returned response is login page, you don't need to do a .get first, just take the response and check if it is login page. And to make it easier, you might want to override jQuery.fn.load function. For example:

(function($){
    // reference to the original load method.
    window["original_jqload"] = jQuery.fn.load;

    // overriding load.
    $.fn.load = function(){
         // check the msg = arguments[0]
         if (arguments[0].indexOf('my distinguishing feature of the login page') >= 0) {
             window.top.location = "login.aspx";
         }
         else {
             // call original method.
             window["original_jqload"] .apply(this, arguments);
         }
    }
})(jQuery);

Open in new window

0
 
Duy PhamFreelance IT ConsultantCommented:
You can't detect session timeout from client-side (using javascript) without requesting information from server.

A simple solution could be that:
1. Add a specific variable to Session on Session Start (Global.aspx.cs)
void Session_Start(object sender, EventArgs e)
{
    Session["MyCustomSessionVariable"] = Guid.NewGuid();
}

Open in new window


2. Create an empty IsSessionTimeout.aspx page
IsSessionTimeout.aspx code
{"timeout": <%=Session["MyCustomSessionVariable"] == null ? "true" : "false" %>}

Open in new window

Make sure to allow anonymous access to that IsSessionTimeout.aspx (in web.config).

3. Perform Ajax call to IsSessionTimeout.aspx page to get the response (in JSON format), parse it to see if session timeout and do what you need to do next.
var isTimeout = false;
$.ajax({
    method: "POST",
    url: "IsSessionTimeout.aspx",
    success: function(responseText) { isTimeout = $.parseJSON(responseText).timeout == "true"; }
});

if (isTimeout) {
    window.top.location = "Login.aspx"; // redirect to login page
}
else {
    // do your ajax call to get content here
}

Open in new window


Another way could be that at page load create a javascript timer (window.setTimeout) with interval is <%=Session.Timeout%> and when timer elapsed, either redirect to login page or do what you want. Note that you will need to reset the timer each time a server call is made, so it will require more effort to get it work properly.
0
 
skijCommented:
I would create a page called: "session.aspx" that would output either:
sessionStatus(true);
or
sessionStatus(false);
depending on if the session is active or expired.

Then use it like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">


function sessionStatus(status) {
 if(status) $('.ss').html('Active');
 else $('.ss').html('Expired');
}

window.setInterval(function(){
    $('#sessionTest').remove()
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.id = 'sessionTest';
    script.src = 'session.aspx';
    head.appendChild(script);
}, 5000);


</script>
</head>
<body>

<h1>Hello World</h1> 
<h2>Session Status: <em class="ss"></em></h2> 

</body>
</html>

Open in new window

0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
BobHavertyComhAuthor Commented:
Both of these solutions might work, but neither seems to be in sync with the site session variables. I am hoping that I don't have to do a balancing act between the expiration of a cookie based site session variable, and a javascript counter based variable. If I could use jQuery to go out and see if the cookie or ASP.NET session variable still exists, that would be really easy, but I don't know exactly how to do this. Also, this web app might be used on a mobile phone. So I do not know how to access the info using jQuery, and I do not even know where to check for it, and the place to check for it could be a different place each time, based on browser, or whether someone is desktop or phone.

Here is my jQuery
var phone = $("#phone").val();
    var address = $("#address").val();
    var msg = encodeURI("addresses.aspx?PhoneNumber=" + phone + "&Address=" + address + "&Dispatcher=" + dispatcher);
    $("#addresses").load(msg);

Open in new window


Is it possible to do a .get first instead of load, and put that into a variable and then check for a distinguishing feature of the login page such as it's title tag, and if it comes back as the login page, then redirect the entire page to the login page and if it does not come back with the distinguishing feature login page then call the load method?
0
 
BobHavertyComhAuthor Commented:
skij,

I think I understand you're approach and it can work, except that I don't want the info displayed, I want to redirect to the login page. So if I do a "test" .get call against session.aspx, to see if the session is still valid or not, before I do the load from the page I really want the data from, I can have session.aspx return a simple string value of true or false, and if false, redirect the page, if true do the load. Let me see if I can work out how to do that. It sounds like a very clever idea that will never have a conflict.
0
 
skijCommented:
Here are some things to keep in mind:

1) In the ASP.NET page that you use to detect the session, make sure to send a header that prevent caching and a header to define the content type as JavaScript.  For example:
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Cache-Control", "no-cache, no-store");
Response.AddHeader("Content-Type", "application/javascript");
Response.Write("sessionStatus(true);");
Response.Flush();
Response.End(); 

Open in new window

2)If you want to redirect when the session expires, you can use this JavaScript code instead of the one I first posted:
function sessionStatus(status) {
 if(!status) document.location='/login.aspx';
}

Open in new window

0
 
BobHavertyComhAuthor Commented:
I create a page called ajaxHandler.aspx. Here is the code behind

public partial class ajaxHandler : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(Session["fullname"].ToString());
        /*if (Session["fullname"] == null || Session["fullname"].ToString() == "null" || Session["fullname"].ToString() == "")
        {
            Response.Write("false");
        }
        else 
        {
            Response.Write("true");
        }*/
    }
}

Open in new window

This page has authentication released from it

<location path="ajaxHandler.aspx">
    <system.web>
      <authorization>
        <allow users ="*" />
      </authorization>
    </system.web>
  </location>

Open in new window


Session Timeout
<authentication mode="Forms"><forms name=".ASPXAUTH" loginUrl="login.aspx" timeout="1" />

Open in new window


The commented out true/false check always returns true after even 5 minutes. The non commented out code always returns the username for the session. I can try to go to another page that needs authentication, and it will redirect to the login page because I am no longer authenticated. But if I go to ajaxHandler.aspx directly, it shows me the username when it no longer should.
0
 
BobHavertyComhAuthor Commented:
Hi skij, I altered my code as recommended

protected void Page_Load(object sender, EventArgs e)
    {
        Response.Clear();
        Response.ClearHeaders();
        Response.AddHeader("Cache-Control", "no-cache, no-store");
        Response.Write(Session["fullname"].ToString());
        Response.Flush();
        Response.End(); 
        
    }

Open in new window


And I cleared the cache and cookies via the browser, but it still shows the username when it no longer should. Really really weird.
0
 
BobHavertyComhAuthor Commented:
Hi Duy,
Following your idea of detecting timeout by checking if returned response is login page, you don't need to do a .get first, just take the response and check if it is login page. And to make it easier, you might want to override jQuery.fn.load function. For example:

This is a really good idea as well and it can definitely work. I might try something like this. Is there some way to simply check the value of the title tag coming back? How do you parse that out of the result set? I am using the simple AHAH method, so all html from the login page will be returned rather than json.

If I do what you suggest, I would not even have to create another aspx page, so the idea has a lot of appeal.

Again, both of your ideas and skij's ideas are very clever.
0
 
Duy PhamFreelance IT ConsultantCommented:
Since all html from the login page is always returned, I don't see any other simpler way to check than .indexOf(). Don't make it more complicated by using an advanced parser.

On the other hand, I think you might want to put in login page some specific key to identify the login page from rendered html (meta tag, keywords, hidden field, or even just a comment, etc.). Checking on the title could be problem if you want to support localization later.
0
 
dejaanbuCommented:
If i understand correctly, ... you want to check, whether ur session variable is set or not, before accessing addresses.aspx.

If i am right, in ur addresses.aspx 's page load event, u can check ur session variable is set or not ,and then redirect to login page if it is not set?

does that help?
0
 
BobHavertyComhAuthor Commented:
If i understand correctly, ... you want to check, whether ur session variable is set or not, before accessing addresses.aspx.

If i am right, in ur addresses.aspx 's page load event, u can check ur session variable is set or not ,and then redirect to login page if it is not set?

does that help? 

Open in new window


The problem is that the response itself is meant for insertion into a page, not a full page refresh, so if the login page gets returned, that will be inserted into a section of the calling page, and it will cause the page to now have two forms which asp.net does not allow for, and as far as I can tell, one of them simply gets kicked out.
0
 
skijCommented:
With my concept, you should NOT output the session name like this:
Response.Write(Session["fullname"].ToString());

Open in new window

Instead you should output a JavaScript function call based on if the session is active or not, like this:
if (Session["fullname"] == null) {
 Response.Write("sessionStatus(false);");
}
else {
 Response.Write("sessionStatus(true);");
}

Open in new window

0
 
BobHavertyComhAuthor Commented:
Thanks guys. Great ideas. What I ended up doing was to create an empty div on the login page with an id of "somethingUnique", and then parsed the return value of the $.get using indexof() to check if that div came back. I might use a guid in the future, but this is always going to be a small site.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.