Как перенаправлять 403 на .php скрипт

Имеется такая конфигурация:

server {
    listen 80;
    listen [::]:80;
    server_name mywebsite.site;

    root /var/www/mywebsite.site/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
    }
}

И пример папки public:

/index.php
/assets/
/assets/img.jpg

Соответственно если я запрашиваю:

  1. mywebsite.site/img.jpg - обрабатывает index.php
  2. mywebsite.site/assets/img.jpg - получаю картинку
  3. mywebsite.site/assets - то получаю 403, т.к. это директория.

Хотелось бы попросить помощи и узнать как 403 ошибку (из-за директории), обрабатывать index.php файлом (как в первом случае), сохраняя урл.

P.S. Хотелось бы универсального решения, без прописывания каждой директории вручную.

Спасибо :)


Ответы (3 шт):

Автор решения: Solt

Добавьте следующее:

location ~ ^/.+/ {
    try_files $uri $uri/ /index.php;
}
→ Ссылка
Автор решения: Manitikyl

Разобрался:

location / {
    try_files $uri $uri /index.php;
}

Надо было убрать / который указывает на проверку директории...

→ Ссылка
Автор решения: Ivan Shatsky

Каждый лишний параметр директивы try_files - это лишний syscall stat(), и вам это точно не надо. И вообще, если можно не использовать директиву try_files - не надо её использовать.

Если вы хотите, чтобы даже обращение к директории без индексного файла перенаправлялось на index.php в корневом каталоге, можно просто задать индексный файл как URI (то есть как путь относительно корневой директории сайта, начинающийся со слеша):

index  index.php index.html /index.php;

Если любые запросы, кроме запросов к статическим файлам, должны обрабатываться файлом index.php в корневой директории сайта (каждый дополнительный параметр директивы index - это тоже лишний syscall fstat():

index  /index.php;

А самое оптимальное решение с точки зрения производительности - это вместо директивы try_files использовать директиву error_page:

error_page 403 404 = /index.php;

Подробнее на enSO: https://stackoverflow.com/a/62377527/7121513


Важное дополнение:

Следует учитывать, что поведение директив

index  <file> [<file>...] <uri>;

(то есть когда хотя бы один индексный файл задан как файл), и

index  <uri>;

(то есть когда директива index имеет единственный параметр, заданный в виде URI), немного отличается. Конкретнее, отличаться оно будет в случае получения входящего запроса вида /some/path/ (заканчивающегося слешом, это важно), если этот путь не соответствует физической директории относительно корня веб-сайта. В первом случае nginx проверит существование первого из индексных файлов, обнаружит, что не существует даже сама директория /some/path/, и вернёт ошибку 404 Not Found. Во втором случае такая проверка выполнена не будет, и nginx сразу вернёт содержимое основного индексного файла.

→ Ссылка