Предотвращение всплывающего окна аутентификации 401 с помощью CouchDB PouchDB

Для веб-приложения JavaScript (на основе AngularJS) я использую PouchDB, реплицирующий базу данных CouchDB на моем сервере. Аутентификация в PouchDB отлично работает с pouchdb-authentication. Я хочу управлять этим через экран входа в систему html/js.

Однако, если пользователь вводит неверные учетные данные, я получаю 401 Unauthorized от сервера CouchDB, который вызывает всплывающее окно браузера с запросом учетных данных.

Как я могу предотвратить это уродливое всплывающее окно аутентификации и просто обрабатывать все из моего javascript?!


person sleidig    schedule 19.09.2015    source источник
comment
не могли бы вы пометить один из ответов как принятое решение?   -  person TylerDurden    schedule 20.01.2016


Ответы (3)


Я наконец нашел решение:

Отредактируйте конфигурацию CouchDB local.ini и измените заголовок HTTP, отправленный в ответ:

WWW-Authenticate = Other realm="app"

Первоначально это

WWW-Authenticate = Basic realm="administrator"

или если он прокомментирован, это то, что все равно отправляется. WWW-Authenticate = Basic, по-видимому, заставляет браузер обрабатывать (неудачную) аутентификацию, показывая ее модальное окно. Изменение Basic на что-либо другое заставляет браузер игнорировать его, и вы можете самостоятельно разобраться с логином.

person sleidig    schedule 19.09.2015

Обновление 2015.12.18

После долгих испытаний я пришел ко второму изложенному решению. Все, что вам нужно сделать, это установить nginx с модулем headers-more-module. Добавьте следующее в ваш nginx-config:

location / {

    # forward all request headers to backend
    proxy_pass_request_headers on;

    # these settings come from the CouchDB wiki
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    # your CouchDB backend
    proxy_pass http://127.0.0.1:5984;

    # replace WWW-Authenticate header in response if authorization failed
    more_set_headers -s 401 'WWW-Authenticate: Other realm="App"';
}

# location to handle access to Futon
location /_utils/ {

    # forward all request headers to backend
    proxy_pass_request_headers on;

    # these settings come from the CouchDB wiki
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    # your CouchDB backend
    proxy_pass http://127.0.0.1:5984;

    # DO NOT replace WWW-Authenticate header in response if authorization failed
    # more_set_headers -s 401 'WWW-Authenticate: Other realm="App"';

    # Handle redirects
    proxy_redirect default;
}

И ваши настроены. Вы можете продолжить использовать pouchdb-authentication или написать свой собственный обработчик входа в систему.

Исходное сообщение

Извините, что отвечаю, но я не могу комментировать (пока).

Я страдаю от той же проблемы, еще хуже, что в OS X параметр WWW-Authenticate отображается в нижнем регистре при каждом перезапуске CouchDB и, следовательно, больше не распознается. Поэтому его необходимо устанавливать после КАЖДОГО перезапуска с использованием Futon/Fauxton или API.

Вы можете попробовать поиграть со следующим параметром (см. http://docs.couchdb.org/en/1.6.1/api/server/authn.html). В принципе, вы отправляете свой запрос на авторизацию (пример в angular2):

// assuming you bootstrapped HTTP_PROVIDERS and injected Http

// configure headers
let headers: Headers = new Headers()
headers.append('Content-Type', 'application/json')
headers.append('Accept', 'application/json')
headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password))

// using the injected Http instance
this.http
// post to _session specifying next and the redirect
.post(
  'http://localhost:5984/_session?next=/successfullyLoggedInPage'
  , JSON.stringify({'name': username, 'password': password})
  , {headers: headers}
)
.map((res: Response) => res.json())
.subscribe(
  (res) => {
    // successful auth
  },
  (err) => {
    if (err.status === 401) // failed auth
  }
)

В моей настройке веб-приложение и CouchDB обслуживаются из двух разных источников. Я могу заставить это работать, только если я отключу веб-безопасность в Chrome из-за ограничений между источниками. Я считаю, что обратный прокси-сервер может переписать ответ перенаправления, например. г. используя proxy_redirect nginx (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect).

Я считаю, что лучшим решением является изменение заголовков ответов с помощью обратного прокси-сервера. Для nginx есть модуль ngx_headers_more (см. https://github.com/openresty/headers-more-nginx-module#readme), который должен это сделать. Можно проверить ответы 401, а затем изменить заголовок с Аутентификация: Базовый на Аутентификация: Другое, отключив модальное окно. В принципе, футон/фокстон все равно должен работать, не так ли? Я еще не пробовал этот подход, но в блоке местоположения nginx вам нужно указать

more_set_headers -s 401 'WWW-Authenticate: Other realm="App"'

Я надеюсь, что кто-то более квалифицированный может добавить свои два цента.

person TylerDurden    schedule 17.12.2015

У меня была более-менее такая же проблема. Хотя я использую обратный прокси-сервер с обработчиком аутентификации «прокси» CouchDB. Когда пользователь пытается сделать что-то, что ему не разрешено (создание БД, когда он не является администратором), CouchDB возвращает ответ 401, запуская базовую аутентификацию HTTP. Не очень приятно, так как обратный прокси обрабатывает аутентификацию на основе клиентских сертификатов X509. Я на самом деле думаю, что CouchDB должен возвращать ответ 403, но это другое обсуждение.

Чтобы исправить это, я использовал ваши ответы, но я не очень хочу использовать внешний модуль Nginx (ngx_headers_more) и на самом деле не очень люблю менять заголовок на «бессмысленное». Вместо этого с существующим прокси-модулем в Nginx вы можете просто удалить WWW-Authenticate целиком:

proxy_pass              http://${COUCHDB_HOSTNAME}:${COUCHDB_PORT};
proxy_hide_header       WWW-Authenticate;

Кажется, работает нормально. См. https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header за документацию.

person Niek Bosch    schedule 20.05.2017