Защищенные документы с помощью PHP

У меня есть простая система контроля входа / доступа для защиты некоторых ограниченных страниц, но на этих страницах есть ссылки, которые должны быть безопасными, то есть документы Word. Поэтому, если я сохраню эти ресурсы в пределах веб-сайта, они смогут получить доступ через URL-адрес. Каков наилучший способ защитить эти ресурсы, которые находятся на ограниченной странице. Я знаю, что могу защитить паролем пароли, но затем пользователю будет предложено дважды бросить вызов, один для ограниченной страницы, а затем для ссылки ресурса. Любой совет ?

У вас есть несколько вариантов здесь, в зависимости от вашего прецедента.

  1. Используйте PHP для работы с файлом. В принципе, либо перехватите все попытки прочитать файл с помощью PHP (с использованием правила mod_rewrite), либо напрямую связать с PHP, и поместить файл под корневого документа. Затем используйте что-то вроде fpassthru для отправки файла в браузер. Обратите внимание, что вы должны правильно настроить заголовки содержимого. Также обратите внимание, что это приведет к большому количеству ресурсов сервера, так как серверу необходимо прочитать весь файл на PHP и отправить его, так что это легко, но не свет.

     $f = fopen('file.doc', 'r'); if (!$f) { //Tell User Can't Open File! } header('Content-Type: ...'); header('Content-Length: '.filesize('file.doc')); fpassthru($f); die(); 

    Главное преимущество этого в том, что он прост и переносится (будет работать на всех серверах). Но вы торгуете ценными ресурсами сервера (поскольку пока PHP работает с файлом, он не может обслуживать другую страницу) для этой выгоды …

  2. Используйте веб-сервер для отправки файла с помощью чего-то вроде X-SendFile (Lighttpd), X-SendFile (Apache2 / 2.2) или X-Accel-Redirect (NginX). Таким образом, вы перенаправляете все запросы в файл на PHP (вручную или переписываете). В PHP вы сделаете свою аутентификацию. Вы отправляете заголовки Content-Type, а затем отправляете заголовок, например X-SendFile: /foo/file.doc . Сервер фактически отправит файл, поэтому вам не нужно (это намного эффективнее, чем отправка из PHP изначально).

     header('Content-Type: ...'); header('X-SendFile: /foo/file.doc'); die(); 

    Основное преимущество здесь в том, что вам не нужно обслуживать файл с PHP. Вы все равно можете выполнить всю свою аутентификацию и регистрацию, которые хотите, но освободите PHP, как только начнете передачу файла.

  3. Используйте что-то вроде mod_secdownload (lighttpd) или mod_auth_token (Apache). В принципе, вы создаете токен в PHP при создании ссылки на файл. Этот токен представляет собой комбинацию MD5 секретного пароля в сочетании с текущей меткой времени. Преимущество здесь в том, что URL-адрес действителен только для того, как долго вы укажете конфигурацию (по умолчанию 60 секунд). Это означает, что ссылка, которую вы выдаете, будет активна только в течение 60 секунд, а затем любые дальнейшие попытки увидеть содержимое вызовут ошибку серии 400 (я не уверен, что у меня на голове).

     $filename = '/file.doc'; $secret = 'your-configured-secret-string'; $time = dechex(time()); $token = md5($secret . $filename . $time); $url = "/downloads/$token/$time$filename"; echo "<a href="$url">Click Here To Download</a>"; 

    Главным преимуществом для этого является то, что с реализацией очень мало накладных расходов. Но вам нужно быть уверенным, что URL-адреса действительны только для установленного времени (по умолчанию 60 секунд) …

  4. Нажмите его на CDN для обработки. Это похоже на вариант № 3 (выше), но использует CDN для обработки файлового сервера вместо локального сервера. Некоторые CDN, такие как EdgeCast, обеспечивают аналогичную функциональность, где вы устанавливаете токен, который истекает через определенное количество времени. Этот случай будет работать хорошо, если у вас много трафика и может оправдать расходы CDN. (Примечание: нет привязки к связанному CDN, только связанные, потому что я знаю, что они предлагают функциональность).

Насколько я лично это сделал, я сделал все вышеперечисленное. Это действительно имеет значение для вашего прецедента. Если вы создаете систему, которая будет установлена ​​на общих хостах или на нескольких разных серверах, которые вы не контролируете, придерживайтесь первого варианта. Если у вас есть полный контроль и вам нужно сохранить ресурсы сервера, сделайте одно из двух других.

Примечание: есть и другие варианты, кроме этих трех. Это проще всего реализовать, и большинство других вариантов достаточно похожи на них, чтобы вписаться в категорию …

Я не пробовал это с помощью текстовых документов (только с изображениями), но я попытался бы обслуживать документ непосредственно с php, см. Мой ответ об изображениях .

Это будет что-то вроде тега, связанного с php-страницей, которая будет использовать документ Word в качестве своего типа содержимого.