views:

1135

answers:

5

I'm sure you're all familiar with the voting systems that use AJAX (Um... look right over there <----)

I have something similar and when you vote up or down it uses AJAX to request the new value from votes.php. The problem is that I am using a session to get the userid so a person can only vote once. What happens if they sit on the page for an hour and then vote so the session is no longer there? What would be a good way of handling this situation? Should I redirect their page to the login screen? If so, how can I do that from the votes.php page that is being referenced by the AJAX request? Am I overlooking a good way of handling this situation? Any advice would be helpful.

A: 

You structure the Javascript code that makes the Ajax request to accept a special result (say, -1 where a >=0 number would normally be, such as, a count of votes) to mean "sorry bub, you're timed out" and redirect to the re-login page (which can take as an optional parameter a message explaining to the user they timed out, &c).

Alex Martelli
+4  A: 

Consider returning an http status of 401, and a JSON object detailing the reason. If you're using jQuery, that'll drop you to the error() callback, which you can then parse your object.

$.ajax({
  data: {},
  dataType: 'html',
  success: function(data) {
    // do whatever here
  },
  type: 'POST',
  url: 'myserver.com',
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    // XMLHttpRequest.responseText has your json string
    // XMLHttpRequest.status has the 401 status code
    if (XMLHttpRequest.status === 401) {
      location.href = 'login.php';
    }
  }
});

I'm not familiar with PHP anymore, but this should work for just about any environment. You may have to suppress any automatic login form redirection though. In asp.net mvc the framework will see the 401 and push the default login form back, with a status of 200.

swilliams
I'll give you $0 if you can tell me how to properly return a 401
Joe Philllips
In ASP.NET you just set Response.StatusCode = 401; Couldn't tell you how to in PHP though... maybe one day someone will build a website that'll let you ask programming questions ;-p
swilliams
I actually tried this out and it ends up popping up an Http authentication box asking for your username and password. This isn't quite the functionality I'm looking for.
Joe Philllips
I guess it may have been because of this line, I'm testing without it now: header('WWW-Authenticate: Basic Realm="Login please"');
Joe Philllips
You don't HAVE to use 401. 500 would work too, though it's not quite as explicit.
swilliams
After removing that line it works.
Joe Philllips
+1  A: 

You should only store a link to the users identity in the session. Use sessions to identify a user as x and then get user x's information from the database.

If your problem is with users sessions timing out then you should reconsider how you're using your sessions. Perhaps make them last until the browser closes? If you really want to make them a duration, then perhaps ping the server in intervals to keep the session alive.

Decide in your php script whether or not the user should be able to vote. If the session isn't set, or if they have already voted, return a message that you can identify with on the client side. If they already voted perhaps return "voted":"true" in a JSON object. Use JS to parse this object and understand what it means, taking the appropriate action. If the session isn't set, perhaps return "session_set":"false", and then make javascript redirect with a window.location = "login.php" etc.

Only increment the counter for the user on a successful return of a counted vote.

Ian Elliott
fyi, I am only storing the userid in the session
Joe Philllips
Was just making sure, it wasn't quite clear :x
Ian Elliott
A: 

You could create a javascript function that could ping the server every 10 minutes via something like

setTimeout("Ping()", 60000);

If you want to navigate the user to the login page if they connect with a faulty session then I would first verify the session and if it fails send a

header("Location: ...");

http://ca2.php.net/manual/en/function.header.php

Patrick Gryciuk
A: 

From a user perspective, the best solution is to pop up a message and login form, saying something like "You are not logged in or your session timed out". Digg does this very well.

As for the actual AJAX implementation, swilliams' 401 suggestion is solid. Alternatively, you can simply return a specific string on failure.

DisgruntledGoat