Handling Permissions for AJAX Requests

Posted in Code, Tips and Tricks

Again I have a website where a lot of data transfer is done asynchronously and a large amount of the presentation is done using Javascript. Different users have different access to features across the site, and I can’t just rely on hiding links given the data is a simple HTTP request away. Protecting this data on the server side has always been easy to me, but I’ve typically found building the persistent abstractions I like to have far more difficult on the client side. As per usual, it’s probably just another issue I haven’t spent enough time to get a grip on.

It’s possible technologies such as Prism and Gears will help with this in the future. Unfortunately, it is the present.

This time I think I have a solution that I’m pretty happy with though. On the server side it involves using the existing HTTP response codes to indicate to the requester what happened with their request. On the client side the ajaxComplete() event is used to handle these codes.

jQuery will automatically call the function you specify as your callback in an AJAX request if the request is successful, so I’m only interested in handling failures. At the moment I’m assuming that all of my calls use JSON for their data format, but the alternative is a case I can handle later if need be. Only do what is necessary right now is a great credo I think.

So here is my event handler, it’s very simple but the documentation on the arguments to the event are a little slight. The success() call just makes a call to the function specified in the original call, hence passing in an empty array, simulating no records returned. The code I’m handling is for 401: Unauthorized, which in this case is the truth. This code will be sent back when I determine that the user is trying to access some data they aren’t supposed to. HTTP codes handle the majority of cases you’ll run into.

(function() {
	if (typeof(jQuery) != 'undefined') {
		jQuery().ajaxComplete(function(ev, req, settings) {
			if (req.status == 401) {
				settings.success([]);
				alert('You have insufficient privileges.');
			}
		});
	}
})();

The server side code is simple, it’s just a matter of sending back the appropriate header:

	header('HTTP/1.0 401 Insufficient Privileges', false, 401);

This function is specified in a global include where part of the website uses prototype, I’ve been slowly integrating jQuery. Therefore the first thing I do is check if jQuery has been defined, if it has then I register my function as the handler for the ajaxComplete event. Since it’s declared globally this will happen on every AJAX call. If the response code is 401 then first I pass back and empty array to my success handler so that the little loading notifier disappears, and then I notify the user of the error.

It seems to be a trend lately, but again this is just a very simple idea but I hope it saves someone some hassle. I know I’ve searched high and low on the topic and haven’t found a nice generic solution.

4 Comments

  • blinds

    Jan 5, 2009

    How do you manage not to get the “enter your password”-dialog every browser shows on a 401 error?

  • aaron

    Jan 5, 2009

    That’s how a browser handles a 401 response for the user. In this case I am handling a 401 for an asynchronous call made by the script itself.

    I guess the way I would think about it is that if I request a page that I am not authorised for the http response status code is 401. Upon receiving this the browser prompts me for a username and password. However if the script requests a page that the user isn’t authorised to access then the response code is 401 and it’s up to the script to handle it. Providing a username and password dialog box to a script isn’t too useful :)

    I hope this helps.

  • Ted McFadden

    Feb 3, 2009

    Follow up on the browser popping up the authentication dialog:

    The browser will only pop up the dialog if it understands the
    WWW-authenticate header that is returned from the server (usually BASIC or DIGEST). If this is the case, the javascript never sees the 401 from an ajax call.

    If WWW-Authenticate defines another scheme, (or is missing?) the 401 will be passed back up to the javascript and you can handle it in code yourself.

  • Matze

    May 19, 2011

    Thanks a lot, exactly what I need

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Twitter

The latest @rubyfive podcast is up, our own @sj26 receiving a mention for Ruby 1.9.3 performance improvements. http://t.co/hfx3EPMz

@frontiergroup about 4 days ago #

Search Posts

Featured Posts

Categories

Archives

View more archives