Это текущая папка:
/app
/dist
/index.html
/index.css
/index.js
/src
/configurations.json
/index.php
/configurations.php
У меня повсюду конфиденциальные данные:
app/src/...
/...
Я хочу, чтобы пользователи могли получить доступ только к:
index.php
app/dist/whateverfile.whateverformat
Папка dist
может меняться, поэтому мне приходится разрешить им статический доступ к этому каталогу, чтобы мне не приходилось перечислять каждый отдельный файл.
Как это сделать с помощью этого .htaccess
синтаксиса?
У меня есть эта конфигурация, которая позволяет мне получить доступ к index.php
. Но нет ни малейшего понятия, как добиться этого для dist
папки...
Options -Indexes
DirectoryIndex index.php
<FilesMatch ".*">
Order allow,deny
Deny from all
Satisfy All
</FilesMatch>
<Files index.php>
Order allow,deny
Allow from all
Satisfy All
</Files>
<Files "">
Order allow,deny
Allow from all
Satisfy All
</Files>
Заранее спасибо.
решение1
Директивы <Files>
и <FilesMatch>
нацелены только нафайлы, а не каталоги. Если у вас есть доступ к конфигурации сервера, то, возможно, вы бы использовали контейнер <Directory>
.
Использование mod_rewrite
В .htaccess
вы можете использовать mod_rewrite, чтобы ограничить доступ ко всему, кроме /index.php
или /app/dist/
.
Например:
RewriteEngine On
RewriteRule !^(index\.php$|app/dist/) - [F]
Вышеуказанное ответит 403 Forbidden для любого запроса, который не является /index.php
или не начинается /app/dist/
. Если вы хотите вернуть 404 вместо этого, измените F
на R=404
.
Префикс !
в регулярном выражении отрицает регулярное выражение. Обратите внимание, что URL-путь, соответствующийRewriteRule
шаблонне начинается с косой черты.
Если вы хотите отвечать кодом 403 только на запросы, которые будут сопоставляться с реальными файлами или каталогами (и кодом 404 в противном случае), то добавьте пару условий, которые проверяют файловую систему (но учтите, что проверки файловой системы относительно дороги, поэтому, если они вам не нужны, не используйте их). Например:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule !^(index\.php$|app/dist/) - [F]
Только если запрошенный URL не входит в разрешенную «группу»исопоставляется с файлом или каталогом — это RewriteRule
директива, которая действует.
Однако я бы предположил, что ваши URL-адреса на самом деле не содержат index.php
(не содержат ли?), в этом случае пользователь запрашивает /
, а mod_dir выдает внутренний подзапрос для /index.php
( DirectoryIndex
). В этом случае вам нужно будет сделать index.php
необязательным.
Например:
RewriteRule !^((index\.php)?$|app/dist/) - [F]
Использование выражения Apache
В качестве альтернативы вы можете сделать это с помощью выражения Apache (Apache 2.4)
<If "%{REQUEST_URI} !~ m#^/((index\.php)?$|app/dist/)#">
Require all denied
</If>
Вышеприведенный код возвращает ответ 403 для любого URL-запроса, который не является /
, /index.php
или начинается с /app/dist/
.
Обратите внимание, что Order
, Allow
, Deny
, и т. д. являются устаревшими директивами Apache 2.2 и официально объявлены устаревшими в Apache 2.4.
Использование mod_setenvif
Другой альтернативой является использование mod_setenvif и установка переменной окружения, если запрашивается один из разрешенных URL-путей, и разрешение доступа только в том случае, если установлена эта переменная окружения.
Например:
SetEnvIf Request_URI "^/((index\.php)?$|app/dist/)" ALLOWED
Require env ALLOWED
Вышеуказанное устанавливает ALLOWED
env var, если запрашивается любой из разрешенных URL-путей. Require
Затем директива требует, чтобы эта env var была установлена для предоставления доступа, в противном случае возвращается 403.
решение2
Если это ваша главная проблема:«У меня везде есть конфиденциальные данные»
Самый простой и надежный способ решения этой проблемы — переместить уязвимость куда-нибудь за пределы корневого каталога вашего веб-сайта...
Рассмотрим корневой веб-каталог (ваш DocumentRoot
), содержащий только . index.php
Если там нет других данных, вам также не нужны сложные правила для его защиты...
Затем вы можете использовать, например,Alias
директива (предпочтительно в файле конфигурации вашего основного сервера или, если вы предпочитаете, .htaccess
в файле в корневом каталоге вашего веб-сайта) или правила mod_rewrite для сопоставления URI с документами, хранящимися в каталогах за пределами ваших каталогов/файлов DocumentRoot, чтобы специально разрешить доступ.
то есть
.
`-- some-path
|-- app
| `-- dist
| |-- index.css
| |-- index.html
| `-- index.js
|-- src
| `-- configurations.json
`-- www.example.com
|-- .htaccess
`-- index.php
Где ваша основная конфигурация Apache определяет /some-path/www.example.com
как DocumentRoot
forwww.example.com.
Тогда .htaccess
может быть что-то вроде этого, что выводит каталог /some-path/app/ и все его содержимое как путь URIhttp://www.example.com/app/
# /some-path/www.example.com/.htaccess
# exposes/some-path/app/ directory as the URI path `http://www.example.com/app/`
Alias "/app" "/some-path/app"
Или будьте более конкретны Alias "/app/dist" "/some-path/app/dist"
или креативны, используя регулярное выражение в AlaisMatch
директиве.
решение3
Вот как:
Options -Indexes
ServerSignature Off
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^ui(/)?$ app/dist/index.html [QSA,END,NC,L]
RewriteRule ui/(.*) app/dist/$1 [QSA,END,NC,L]
RewriteRule !(ui/.*) index.php [QSA,END,NC,L]
Обратите внимание на END
флаг после каждого совпадения. Этот флаг необходим для имитации типичного if-else
синтаксиса. Но он не документирован в официальных документах.
Я наконец-то перешел на Node.js.