Ограничить доступ к файлу - PDF.JS

Обратите внимание на следующее:

У меня есть веб-сайт, на который пользователи загружают контент в формате PDF. Я хотел бы каким-то образом ограничить доступ к этому контенту. План состоит в том, чтобы сценарий PHP аутентифицировал пользователя, а затем загружал локальный PDF-файл с помощью PDF.JS, чтобы он работал на всех устройствах.

Я использую код, предоставленный viewer.js.

Я попытался использовать .htaccess, чтобы разрешить загрузку PDF-файлов только в том случае, если они поступают с IP-адреса сервера, но безрезультатно - похоже, что он блокирует любые попытки вытащить PDF-файл с помощью PDF.js

Есть ли способ в PDF.JS заставить его загружать файл локально, а не загружать его как URL-адрес? Возможно, тогда я могу просто deny all в .htaccess и все же разрешить PDF.js загружать его?

Имейте в виду, что я использую код из viewer.js в веб-каталоге стабильной загрузки - я не могу заставить работать ни один из «Примеров» на сайте PDF.JS, в частности эту строку: var pdfjsLib = window['pdfjs-dist/build/pdf']; - Это будет зависеть от моих ограниченных знаний. Если кто сможет это объяснить, бонус.

Я полностью открыт для других способов решения этой проблемы, и я надеюсь, что кто-нибудь скажет мне, что это ужасная идея, и предоставит гораздо лучший способ ее решения.

Редактировать

Просто чтобы подтвердить, поскольку я не думаю, что изначально был очень ясен, я все еще хочу, чтобы пользователи могли просматривать контент через веб-страницу с PDF.JS, однако я не хочу, чтобы кто-либо переходил по прямому URL-пути и возможность просматривать содержимое.

GET считается небезопасным для целей аутентификации. «Поскольку вы используете GET, ключ может легко просочиться через историю браузера или случайно поделиться ссылкой.» И т. Д. security.stackexchange.com/questions/147188/…
HoldOffHunger 03.10.2018 18:41

Да, я понимаю и никогда не буду использовать этот метод для каких-либо "серьезно" безопасных областей. (Обычно это делается для того, чтобы боты не спотыкались) Спасибо за комментарий

Aphire 03.10.2018 18:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
899
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для этого мы используем следующее решение:

  1. Сохраните файлы PDF вне веб-каталога
  2. Получите доступ к PDF-файлу через скрипт (PHP или другой, в моем случае позвольте ему называть его download_file.php) и передать его вашему клиенту с помощью функции читать файл по частям.

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

Таким образом, ваш файл PDF.JS может ссылаться на download_file.php?file_id=123123 вместо my_read_file.pdf, где ваш скрипт может связывать file_id 123123 с фактическим PDF.

Мой сценарий download_file.php выглядит примерно так:

//$filename : full path to your actual file. NOT located in your web directory
//$mime : mime type of your file

header('Pragma: public');
header('Cache-Control: private');
header('Expires: '.gmdate("D, d M Y H:i:s", strtotime("+2 DAYS", time())). " GMT");
header('Last-Modified: '. gmdate("D, d M Y H:i:s", time()). " GMT");
header('Content-Length: '.filesize($filename)); // Get the file size manually
header('Content-type: '. $mime);

set_time_limit(0);
readfile_chunked($filename);

function readfile_chunked ($filename) {
  $chunksize = 1*(1024*1024); // how many bytes per chunk
  $buffer = '';
  $handle = fopen($filename, 'rb');
  if ($handle === false) {
   return false;
  }
  sleep(1);
  while (!feof($handle)) {
   $buffer = fread($handle, $chunksize);
   //if (strlen($buffer) < $chunksize)
   //   $buffer = str_pad($buffer, $chunksize);
   print $buffer;
   // 2006-01-26: Added 
   flush();
   @ob_flush();
 }
  return fclose($handle);
}

Большое спасибо за ответ - это отличная альтернатива.

Aphire 25.10.2018 17:13

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

Royal Wares 25.10.2018 17:17
Ответ принят как подходящий

Создайте pdf.php в качестве конечной точки для получения файлов PDF:

<?php

$file = "tracemonkey.pdf";

if (!$loggedIn) return; // Update with your logic

header("Content-type: application/octet-stream");
header("Content-disposition: attachment;filename = " . $file);

echo file_get_contents(__DIR__ . '/' . $file);

Затем в программе просмотра JS просто замените URL-адрес:

var url = 'pdf.php';

Таким образом, PHP действует как своего рода прокси для ваших файлов, вам нужно будет добавить свою собственную логику для захвата файлов и того, что вы считаете аутентифицированным пользователем, независимо от того, извлекаете ли вы это из GET или имеете систему поиска файлов и т. д.

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

Royal Wares 25.10.2018 16:49

Большое спасибо за такое элегантное решение. Я награжу Баунти, когда смогу (23 часа, кажется, атм)

Aphire 25.10.2018 17:13

Другие вопросы по теме