Я работаю над приложением Symfony 3.4, которое имеет публичную и частную части. Однако в настоящее время я настраиваю промежуточную систему для этого приложения, к которой должны иметь доступ только авторизованные пользователи, поэтому я поставил базовую аутентификацию .htaccess перед всем приложением.
В приложении есть единственный маршрут, к которому должен получить доступ внешнее приложение, не обеспечивающее аутентификацию. Я хочу отключить аутентификацию .htaccess только для этого единственного маршрута. Все URL-адреса для этого маршрута имеют вид /api/post-result/123
где 123
- произвольный идентификатор.
Немного поискав, я попытался решить эту проблему с помощью Require expr
запись в моем .htaccess, которая просто соответствовала бы URL-адресу. Однако, поскольку Symfony выполняет перезапись URL, REQUEST_URI
всегда отображается как "app.php" на сервере (и в моем состоянии). Я пробовал другие переменные, например QUERY_STRING
или PATH_INFO
, но ни один из них, похоже, не содержит моего фактического URI запроса. Затем я попытался поместить согласованный URI в переменную среды, используя правило перезаписи. Однако, похоже, это нельзя прочитать по выражению.
Вот мой файл .htaccess
DirectoryIndex app.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule ^(.*)$ %{ENV:BASE}/app.php [L,E=SFURI:$1] # <-- env variable is set here
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /app.php/
</IfModule>
</IfModule>
<Files "*.php">
AuthUserFile /srv/my/app/.htuser
AuthName "Authentication Required"
AuthType Basic
# allow access to post-result api without authentication
# THIS DOES NOT WORK as reqenv('SFURI') is always empty
Require expr "reqenv('SFURI') =~ m#/api/post-result/.*$#"
# require authentication for everything else
Require valid-user
</Files>
Глядя на журнал Apache, переменная среды установлена правильно:
[rewrite: trace5] [pid 11010] mod_rewrite.c (476): [...] установка переменной env 'SFURI' на 'api / post-result / 123'
[rewrite: trace1] [pid 12755] mod_rewrite.c (476): [...] внутреннее перенаправление с /app.php [ВНУТРЕННЕЕ ПЕРЕАДРЕСАЦИЯ]
Однако по какой-то причине переменная пуста, когда я пытаюсь получить к ней доступ позже. Возможно ли, что все переменные среды очищены при внутреннем перенаправлении, вызванном последним правилом перезаписи? Журнал показывает, что условие не соответствует, и когда я изменяю условие, чтобы он проверял, пуста ли переменная, условие возвращается как истинное. Я также пробовал использовать env
функция вместо reqenv
, но поведение такое же.
[authz_core: trace4] [pid 11010] util_expr_eval.c (860): [...] Оценка выражения из /srv/my/app/.htaccess:36 дала: 0
[authz_core: debug] [pid 11010] mod_authz_core.c (809): [...] AH01626: результат авторизации Require expr "reqenv ('SFURI') = ~ m # / api / post-result /.*$# ": отказано
Что я могу сделать, чтобы мое выражение нашло переменную среды, заданную правилом перезаписи?
Оказывается, внутреннее перенаправление, вызванное последним правилом перезаписи, ставит перед всеми переменными префиксы REDIRECT_
. Чтобы получить доступ к переменной в выражении, к ней нужно обращаться как REDIRECT_SFURI
.
Эта проблема также была рассмотрена на StackOverflow: При установке переменных среды в директивах Apache RewriteRule, что заставляет имя переменной иметь префикс «REDIRECT_»?