Назад | Перейти на главную страницу

Как я могу заставить mod_rewrite отправлять компонент пользовательской информации URI?

Коллега порекомендовал мне опубликовать это из StackOverflow в ServerFault:

Это сводит меня с ума. У меня есть веб-приложение, которое обслуживается через веб-сервер Apache. Сервер базы данных, поддерживающий приложение, - это Apache CouchDB, который предоставляет HTTP API для получения документов и потоковых вложений.

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

Я хочу иметь возможность сопоставлять общедоступные URL-адреса с вложениями документов, хранящимися в этой базе данных. Итак, я попытался создать правило перезаписи в моем файле .htaccess, которое проксирует запросы с определенных URL-адресов непосредственно на CouchDB, жестко кодируя учетные данные пользователя, например:

## DOWNLOAD STREAM:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://user:pass@127.0.0.1:5984/database/$1 [P]

В идеальном мире приведенный выше пример должен принимать следующий URL:

http://example.com/download/UUID/attachment.ext

И проксировать его на:

http://user:pass@127.0.0.1:5984/database/UUID/attachment.ext

Этот метод действительно передает запрос в CouchDB, но опускает компонент userinfo схемы URI. Итак, запрос обрабатывается как анонимный, и я получаю ошибку 401. Вложение передается только в том случае, если я удалю защиту из базы данных.

Я потратил пару часов на чтение конфигурации Apache и безрезультатные эксперименты. Поиск в Интернете бесполезен из-за всех связанных запросов с похожими ключевыми словами.

Как я могу гарантировать, что mod_rewrite включает имя пользователя и пароль, указанные в правиле перезаписи, когда он проксирует CouchDB?

Я понял! Вместо того, чтобы включать имя пользователя: пароль как часть схемы URI, заголовок авторизации должен быть установлен независимо. Следующее решение полностью работает в .htaccess файл, что важно, поскольку OS X периодически сдувает настройки внутри сайтов VirtualHost:

SetEnvIf Request_URI ^/download/* ADD_COUCH_BASIC_AUTH
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=ADD_COUCH_BASIC_AUTH

## DOWNLOAD STREAM
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://127.0.0.1:5984/database/$1 [P]

Как это работает: мы используем SetEnvIf чтобы проверить, соответствует ли путь запроса пути, который мы хотим проксировать, и если да, установите произвольную переменную среды ADD_COUCH_BASIC_AUTH

В следующей строке мы добавляем заголовок Basic Auth к исходящему запросу, только если установленная нами переменная среды существует. Таким образом, основной заголовок аутентификации будет добавлен только при запросе ресурса через /download/, таким образом отправляя учетные данные аутентификации в CouchDB.

Примечание: вам нужно будет кодировать Base64 ваше имя пользователя: пароль и учетные данные и заменить XXXXXXXXXXX с закодированным значением. Простой способ сделать это на Mac:

echo -n 'user:pass' | openssl base64

Надеюсь, это поможет кому-нибудь, кроме меня!