Изящная обработка 401 без разрешения Angularjs $http

В настоящее время я работаю над проблемой со страницей входа в приложение AngularJS. Страница входа использует $http сервис для отправки имени пользователя и пароля с использованием обычной аутентификации (Authorization: Basic (username and password in base 64)) к веб-службе, которая может работать или не работать на том же сервере, на котором размещено веб-приложение. Если аутентификация успешна, сервер возвращает ответ со статусом 200 OK; в противном случае возвращается 401 Not Authorized. У нас есть функция ошибок, чтобы изящно обрабатывать это состояние ошибки, но еще до того, как она была вызвана, браузер по умолчанию показывает модальное диалоговое окно для ввода пользователем своего имени пользователя и пароля. Как я могу предотвратить это?

Я обратился за помощью к нескольким источникам, включая стандарты W3 для XHR.send(), и мои выводы показывают, что в Firefox и Chrome диалоговое окно браузера появляется после ответа 401 на вызов XHR, когда все следующие верны

1) Запрос "того же происхождения" (что происходит в тех случаях, когда веб-служба работает на том же сервере, который обслуживает веб-приложение)

2) Ответ включает в себя заголовок WWW-Authenticate: Basic [some realm] или же WWW-Authenticate: Digest [some realm] (наш веб-сервис возвращает первое)

3) Запрос не был сделан путем конкретной установки имени пользователя и пароля в объекте XHR, чей send() метод был вызван.

Я нашел тестовый сайт (на который ТАК не позволяет ссылаться), который демонстрирует желаемое поведение для 401 ответа (без модального поля входа). Он удовлетворяет первым двум условиям, но избегает выполнения третьего, очевидно, потому что он устанавливает имя пользователя и пароль объекта XHR, отправляя их в качестве аргументов #4 и 5 на его open() функция. Я не уверен, есть ли какой-либо другой способ установить эти свойства объекта XHR, так как я даже не могу найти их, проверяя объект XHR в отладчике JavaScript браузера.

Проблема в том, что служба входа в систему нашего сайта сама по себе не вызывает XmlHttpRequest.open() передать имя пользователя и пароль; вместо этого он сам создает заголовок Authorization и передает его в коллекцию заголовков объекта params $http, Изучив источник angular.js, я обнаружил, что $http затем вызывает open() только с тремя параметрами.

Предоставляет ли Angular способ иметь $http вызвать 5-параметрическую перегрузку open() или иным образом предотвратить появление этого диалогового окна входа в систему? Если нет, я могу думать только о нескольких обходных путях:

1) как-то украсить $http для принудительного вызова 5-параметрической перегрузки open() если указаны имя пользователя и пароль

2) Как-то использовать $httpBackend достичь того же, что и #1 (хотя документация не рекомендует разработчикам использовать $httpBackend так что я не уверен, если это хорошая идея или даже возможно)

3) Игнорировать $http и мой сервис входа в систему создает и отправляет сам XHR

4) Измените сервер, чтобы он не возвращал WWW-Authenticate: Basic заголовок (наименее желательно)

Есть ли известный или "правильный" способ обойти эту проблему?

1 ответ

Проблемы, с которыми вы сталкиваетесь, связаны с первой указанной вами причиной.

1) Запрос "того же происхождения" (что происходит в тех случаях, когда веб-служба работает на том же сервере, который обслуживает веб-приложение).

решение

Либо добавьте заголовок access-control-allow-origin к вашей серверной службе, чтобы принимать вызовы из другого источника.

или же

если вы находитесь в фазе разработки и позже ваш веб-интерфейс и служба в любом случае будут находиться в одном источнике, используйте https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en расширение,

это позволит вам переопределить политику перекрестного происхождения Chrome (это только для разработки, это обходной путь).

или же

Откройте Chrome с отключенной веб-безопасностью, открыв Chrome из командной строки

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Другие вопросы по тегам