I'm building an AngularJS (1.2.16) web app with a RESTful API, and I'd like to send 401 Unauthorized responses for requests where authentication information is invalid or not present. When I do so, even with an HTTP interceptor present, I see the browser-presented basic "Authentication Required" dialog when an AJAX request is made via AngularJS. My interceptor runs after that dialog, which is too late to do something useful.
A concrete example:
My backend API returns 401 for /api/things
unless an authorization token is present. Nice and simple.
On the AngularJS app side, I've looked at the docs and set up an interceptor like this in the config
block:
$httpProvider.interceptors.push(['$q', function ($q) {
return {
'responseError': function (rejection) {
if (rejection.status === 401) {
console.log('Got a 401')
}
return $q.reject(rejection)
}
}
}])
When I load my app, remove the authentication token, and perform an AJAX call to /api/things
(to hopefully trigger the above interceptor), I see this:
If I cancel that dialog, I see the console.log
output of "Got a 401" that I was hoping to see instead of that dialog:
Clearly, the interceptor is working, but it's intercepting too late!
I see numerous posts on the web regarding authentication with AngularJS in situations just like this, and they all seem to use HTTP interceptors, but none of them mention the basic auth dialog popping up. Some erroneous thoughts I had for its appearance included:
- Missing
Content-Type: application/json
header on the response? Nope, it's there. - Need to return something other than promise rejection? That code always runs after the dialog, no matter what gets returned.
Am I missing some setup step or using the interceptor incorrectly?