Я пытаюсь защитить файлы на своем сервере (несколько типов) с помощью NGiNX и PHP.
В основном я хочу, чтобы люди входили на сайт, если они хотят получить доступ к этим статическим файлам, таким как изображения. DropBox делает это очень хорошо. Где они заставляют вас войти в систему, чтобы получить доступ к любым статическим файлам, которые вы размещаете на сервере.
Я думал об использовании модуля NGiNX Perl. И я бы написал сценарий perl, который проверял бы сеанс, чтобы узнать, вошел ли пользователь в систему, чтобы предоставить ему доступ к статическому файлу.
Я бы предпочел использовать PHP, потому что весь мой код работает под PHP, и я не уверен, как проверить сеанс, созданный PHP, с помощью PERL.
Итак, в основном мой вопрос: как я могу защитить статические файлы любых типов, которые потребуют от пользователя входа в систему и создания действительного сеанса с помощью сценария PHP?
Вы спрашиваете о двух вещах:
Надеюсь, это проясняет роль, которую играет каждый компонент, хотя она может быть немного чрезмерной.
Запретить внешний доступ к файлам:
Эта часть выполняется вашим веб-сервером - в данном случае nginx.
В вашей конфигурации nginx (ваш серверный блок) вы указываете root
дорожка. По умолчанию все файлы по этому корневому пути доступны напрямую.
Например, рассмотрим следующее (домен - example.com)
root /var/www/example.com/public_html
Если у вас есть файл, uploaded_file.zip
, он будет доступен следующими способами:
По сути, файл над корнем документа не будет доступен через браузер, однако большинство конфигураций PHP позволяют вашему коду читать файл и доставлять его (ограничения на это часто являются результатом open_basedir
)
В некоторых сценариях может быть предпочтительнее размещать файлы в корне документа. Чтобы сделать это и при этом предотвратить (прямой) внешний доступ, вы будете использовать internal
директива. Например:
расположение / загрузки {внутренние; }
Теперь любые файлы, размещенные в /var/www/example.com/public_html/uploads, доступны только изнутри (т.е. не могут быть доступны через браузер, но могут быть доступны через ваши сценарии PHP). При желании вы также можете настроить псевдоним для местоположения / uploads, чтобы можно было использовать другой путь для ссылки на него.
На данный момент ваши файлы недоступны напрямую, но ваши скрипты все еще могут их обслуживать.
Аутентификация пользователя и PHP:
Рассмотрим следующий базовый дизайн: пользователь может получить доступ к файлу напрямую или перейти на страницу входа. Если они попытаются получить доступ к файлу напрямую и вошли в систему (и имеют разрешение), файл загрузится, в противном случае они окажутся на экране входа в систему. Чтобы загрузить файл, пользователь должен войти в систему.
Допустим, ваш сценарий загрузки (страница, которая доставит файл пользователю) называется «download.php». Типичный URL-адрес может быть example.com/download.php?file=uploaded_file.zip. Вполне вероятно, что вы не хотите, чтобы ваши URL-адреса включали имя файла php. Чтобы этого избежать, вы можете настроить правило перезаписи в своей конфигурации nginx, которое будет указывать другое место (скажем, / files) в вашем скрипте. Добавьте в конфигурацию nginx:
rewrite ^/files/(.*) /download.php?file=$1 last;
(Это означает изменение запрошенного пути любых запросов, начинающихся с / files, и захват всего, что находится после /, и передачу его в качестве параметра запроса в ваш файл php);
Теперь к вашему файлу можно получить доступ через: example.com/files/uploaded_file.zip (который внутренне перенаправляет на ваш php-скрипт).
Ваш PHP-файл (download.php) теперь выполняет следующие функции:
Выведите необходимые заголовки (Content-Type, Content-Disposition и т. Д.) И установите:
X-Accel-Redirect: /uploads/uploaded_file.zip;
Обратите внимание: вы можете выполнить фактическую загрузку полностью с PHP (например, используя readfile
) - просто немного эффективнее, особенно для больших файлов) делать это через nginx. Кроме того, несмотря на то, что пользователь, похоже, обращается к файлу напрямую, внутри он проходит через PHP, который аутентифицирует их, прежде чем разрешить им продолжить.
URL -> nginx (redirect to PHP) -> PHP (authenticate) -> nginx (serve file)
Что касается загрузки, вы будете move_uploaded_file
в /var/www/example.com/public_html/uploads (который защищен «внутренней» директивой, поэтому к файлам нельзя получить прямой доступ) и сохраните разрешения в своей базе данных.