tags:

views:

152

answers:

5

Hi there

Wondering if anyone can assist..

I am adding some jquery to my site, but I want to restrict some actions dependant on whether a user is logged in or not. I am unsure of how to detect the session variable with Jquery..

My initial thought was to call my checkUser cfc using Jquery Ajax and then check how many rows where returned from this, and work from there. But am unsure of how to tackle this. At the moment, my code looks like this

$.getJSON('http://localhost:8500/mxRestore/model/mdl_user.cfc?method=getUserData&returnFormat=json&queryformat=column', {}, function(data){
    var isLoggedIn = data.ROWCOUNT;
})

if (loggedIn > 0) { 
  // Do this
} 
else {
  alert('You are not logged in');
}
}

However, I am getting an error message saying the isLoggedIn variable isnt defined. Wondering how best to deal with this.

Thanks

+1  A: 

You are defining the variable in a callback but using it outside of that scope. You need to move the code that's performing the actions into the callback as well.

$.getJSON('http://localhost:8500/mxRestore/model/mdl_user.cfc?method=getUserData&returnFormat=json&queryformat=column', {}, function(data){
  if (data.ROWCOUNT > 0) {
      // do this
  }
  else {
      alert('You are not logged in');
  }
});

Typically, though, what I'll do is either enable or disable the actions server side -- i.e., not deliver code for actions that are not available. A person with a debugger could always defeat your client-side checks so you need to be very careful in depending on the results of a server call to enforce security and always check on the server as well.

tvanfosson
I have server side security also...thanks
namtax
Or define that variable outside of the scope of the function
bdukes
@bdukes -- the ajax call is asynchronous so defining it outside the function will resolve the undefined reference, but it will not end up working the way you want. You actually need to run the code after the ajax call returns and the way to do that is by running it in the callback.
tvanfosson
A: 

The isLoggedIn variable is out of the scope where you use it, it's available only within the getJSON callback, consider working there:

$.getJSON('...', {}, function(data){
  var isLoggedIn = data.ROWCOUNT > 0; // isLoggedIn is now boolean

  if (isLoggedIn) { 
    // Do something
  } else {
   alert('You are not logged in');
  }
});

I would also recommend you to return a boolean value from the server, instead of exposing a row count.

More info about the function scope:

CMS
Ah, had the same idea of setting `isLoggedIn` to a boolean... and I promise I didn't see your code first :)
Doug Neiner
Thanks very much for your response
namtax
A: 

There are a couple problems:

  1. You define isLoggedIn but reference loggedIn.
  2. You define isLoggedIn inside a function, but reference it outside the function

You can fix with this:

var loggedIn = null;
$.getJSON('http://localhost:8500/mxRestore/model/mdl_user.cfc?method=getUserData&returnFormat=json&queryformat=column', {}, function(data){
   loggedIn = (data.ROWCOUNT > 0);
});

So you can test elsewhere in your code like this:

if(loggedIn){
  // Do something
} else if (loggedIn === false) {
  alert('You are not logged in');
} else {
  // Callback hasn't been run yet
}

If you need to only run this once, just put the whole if statement (minus the else) in your callback from the $.getJSON method.

Doug Neiner
A: 

There are two problems with the code.

The first one, that you have noticed, is that the variable only exists in the scope of the anonymous function that you have created to handle the callback.

The other problem is that the code that uses the variable is executed before the variable is set.

The request to the server is send, then the callback function waits for the response, but the code sending the request doesn't wait for the response, so it will continue with the code using the variable.

Both these problems are solved by moving the code that uses the variable into the callback function.

Alternatively, place the code that uses the variable in a separate function, and call that function from the callback function:

$.getJSON(
  'http://localhost:8500/mxRestore/model/mdl_user.cfc?method=getUserData&returnFormat=json&queryformat=column',
  {},
  function(data) {
    handleCallBack(data.ROWCOUNT > 0);
  }
);


function handleCallBack(isLoggedIn) {
  if (isLoggedIn) { 
    // Do this
  } else {
    alert('You are not logged in');
  }
}
Guffa
+1  A: 

Since you already have a few good answers, let me throw a fair warning into the discussion:

1) It would make a lot more sense to manipulate what the user sees before you send the page down to the client eliminating a lot of complexity from your approach.

2) Don't rely on the client side script as the sole means of securing a feature from users who are not logged in. Client side security code like this can be circumvented by simply turning off scripting or editing the content of the page to comment out the security check.

3) If you absolutely must do it this way, have the server re-check the credentials/login state when an action is initiated, even if the client code already did..

4) The redundant check I suggested in item #3 is another good reason to just do this with server side scripts instead of client side JS/JQUERY.

JohnFx
To explain, I have a link used for voting, with javascript turned off this link is secured by server side code. You cant vote unless you are logged in. With JS turned on, Jquery attaches a function to the vote link which allows ajax voting, but allows those not logged in to vote..How can I make this more secure? Thanks
namtax
A few suggestions 1) instead o using JQuery to turn on the voting link, add the function to the link when you generate the page on the server and send it down with the link activated or deactivated as needed. 2) When the vote is submitted to the server, have the server re-check that the user is allowed to vote, even if through client-side code you wouldn't have expected them to have an active link.
JohnFx
Cool, thanks for the suggestions
namtax