Я работаю над приложением 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 [INTERNAL REDIRECT]
Однако по какой-то причине переменная пуста, когда я пытаюсь чтобы получить к нему доступ позже. Возможно ли, что все переменные среды очищены при внутреннем перенаправлении, вызванном последним правилом перезаписи? Журнал показывает, что условие не соответствует, и когда я изменяю условие, чтобы он проверял, пуста ли переменная, условие возвращается как истинное. Я также пробовал использовать функцию 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 /.*$# ": denied
Что я могу сделать, чтобы мое выражение нашло переменную среды, заданную правилом перезаписи?
Оказывается, внутреннее перенаправление, вызванное последним правилом перезаписи, ставит перед всеми переменными префикс REDIRECT_
. Чтобы получить доступ к переменной в выражении, к ней нужно обращаться как REDIRECT_SFURI
.
Эта проблема также была рассмотрена в StackOverflow: При установке переменных среды в директивах Apache RewriteRule, что вызывает имя переменной должно начинаться с префикса «REDIRECT _»?