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

Htaccess Require expr Apache 2.4 работает на osx-sierra, а не на debian-jessie

На моей машине разработки osx-sierra / apache 2.4.10 (от brew) у меня есть ограничение в VirtualHost, которое разрешает доступ к / api / без пароля, а всем остальным страницам нужен пароль с этим кодом:

<Location />
    AuthType Basic
    AuthName "Access"
    AuthUserFile /Users/xxxxxx/www/public/.htpasswd
    Require expr %{REQUEST_URI} =~ m#^/api/*#
    Require valid-user
</Location>

Когда я пытаюсь сделать это на своем производственном сервере с теми же директивами, Debian-jessie / apache 2.4.29 (от apt), это не работает, пароль всегда запрашивается (chrome / safari / wget), я пробовал эти решения :

1 /

<Location />
    AuthType Basic
    AuthName "Access"
    AuthUserFile /home/xxxxxx/www/public/.htpasswd
    Require expr %{REQUEST_URI} =~ m#^/api/*#
    Require valid-user
</Location>

2 /

<Location />
    AuthType Basic
    AuthName "Access"
    AuthUserFile /home/xxxxxx/www/public/.htpasswd
    Require expr %{REQUEST_URI} =~ m#^/api/.*#
    Require valid-user
</Location>

Есть идеи, почему эти различия?

Спасибо

Зачем так усложнять, вместо того, чтобы делать это прямо?

<Location />
    AuthType Basic
    AuthName "Access"
    AuthUserFile /home/xxxxxx/www/public/.htpasswd
    Require valid-user
</Location>

<Location /api>
        Require all granted
</Location>

Также обратите внимание, ваша предыдущая директива Directory (корневой каталог документов), смешивающая директивы 2.2.x и 2.4.x, могла все испортить.

Бардак:

Order allow,deny
Allow from all
Require all granted

Правильный поступок:

Require all granted
  • Обязательно удалите 2.2. директивы и выгрузите mod_access_compat, чтобы убедиться, что вы делаете - это рецепт получения неожиданных результатов. Также учтите, что файлы .htaccess, которые у вас могут быть, могут повлиять на результат из-за настройки AllowOverride all, которую в идеале вам не следует использовать, если вы являетесь администратором сайта.

Это законченный виртуальный хост, где директивы не работают:

<VirtualHost *:80>
DocumentRoot /home/xxxxxx/www/public
ServerName xxxxxx.com

Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, PUT, GET, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-so-resource, x-so-apikey, x-so-apisecret, x-token, Authorization, Content-Type"

<Directory /home/xxxxxx/www/public>
    php_value include_path "/home/xxxxxx/libs/ZendFramework-1.11.11/library"
    Options +FollowSymLinks 
    AllowOverride All
    Order allow,deny
    Allow from all
    Require all granted
</Directory>

ServerSignature Off

AddDefaultCharset UTF-8

php_value short_open_tag 0

SetEnv APPLICATION_ENV development


<Location />
    RewriteEngine On     
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^.*$ index.php [NC,L]
</Location>


<LocationMatch "^(?!/api/.*$).*$">
    AuthType Basic
    AuthName "Access"
    AuthUserFile /home/xxxxxx/www/public/.htpasswd
    Require valid-user
</LocationMatch>

ErrorLog /var/log/apache2/xxxxxxxx-error.log
CustomLog /var/log/apache2/xxxxxxxx-access.log combined

Я не уверен, почему это будет работать на osx-sierra / Apache 2.4.10, но не на Debian-jessie / Apache 2.4.29. Однако в качестве обходного пути вы можете сделать это по-другому, используя отрицательный взгляд вперед на <LocationMatch> контейнер вместо использования выражений Apache 2.4. Например:

<LocationMatch "^(?!/api/.*$).*$">
    AuthType Basic
    AuthName "Access"
    AuthUserFile /Users/xxxxxx/www/public/.htpasswd
    Require valid-user
</LocationMatch>

Теперь директивы внутри <LocationMatch> контейнер обрабатываются только тогда, когда URL не запускается /api/. (Это также работает на Apache 2.2)