Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Safari from intercepting 401 responses to ajax requests

I'm having the following problem in a Safari extension. I ask the user to provide their username/password for a web service and send off a quick request to verify that the credentials are correct. If they are not, the service will respond with a 401 as I believe it should. The problem is that Safari seems to intercept this response before my javascript code can handle it, showing the grey login box instead of letting me handle the error.

Is there anything I can do about this? I'm using a js library to make the call, but it's functionally equivalent to the following jQuery.

$.ajax({
  type: "GET",
  url: url,
  username: username,
  password: password,
  success: function() { /* handle success */ },
  error: function() { /* handle error */ }
});
like image 975
Eric Seidel Avatar asked Feb 04 '12 01:02

Eric Seidel


2 Answers

As far as I'm aware (after having had this issue myself) there's no way you'll get Safari to stop intercepting a 401. If those findings are correct, the only way is creative (read: mis-) use of another error code, e.g. 403, or using a custom one (see below).

Of course, this assumes that you have access to changing the status code sent back from the web service (it's not entirely clear from the question if you developed the web service too).

403, of course, really says "you're already authenticated, but not authorized to access this resource", which isn't correct (hence "misuse"), but at least it has no side effects in browsers that I'm aware of.

400 is sometimes used as an alternative, but since that one ("bad request") is really meant to signify a HTTP protocol error, it may cause side effects (never seen or heard of it happening, but potentially, it might cause an over-helpful attempt by some future browser or anti-hijacking software to start troubleshooting/diagnostics).

412 is another alternative that I've seen used ("precondition failed"), but it actually is meant to indicate that the server didn't live up to the preconditions the request set.

Or you could make up your own non-standard 4xx error - e.g. 461 - which is allowed (notice that twitter has a custom 420 status code, for example)

like image 61
JimmiTh Avatar answered Nov 23 '22 23:11

JimmiTh


A more correct approach would be to continue to use 401 as the error code but not send the WWW-Authenticate header when the credentials have been sent but they were not correct.

That no longer triggers the browser's dialog and allows you to process 401 directly.

like image 45
sqreept Avatar answered Nov 24 '22 01:11

sqreept