Сокрытие прямых ссылок на файлы в PHP (Laravel)
Сейчас подавляющее большинство фреймворков поддерживают маршрутизацию внутри себя. Задача состоит в том, чтобы запретить пользователю напрямую обращаться к файлу, а преобразовывать пути с помощью функции и выводить результат в браузере. Образец написан на Laravel:
В начале мы должны удалить неподдерживаемые символы URL. Я использую класс Helpers для хранения функций.
public static function base64url_encode($s) {
return str_replace(array('+', '/'), array('-', ''), base64_encode($s));
}
public static function base64url_decode($s) {
return base64_decode(str_replace(array('-', ''), array('+', '/'), $s));
}
Затем пишем необходимые функции кодирования / декодирования
Чтобы поймать URL-адреса в браузере, нам нужно написать маршрут. Файлы сохраняются в стандартном хранилище и в подпапках Laravel. Итак, если мы хотим сохранить файлы из формы, мы должны написать функцию в нужном нам контроллере, я сохраняю файлы в 'app/public/poadata' Чтобы показать ссылки для сохраненных файлов, вы можете использовать код ниже. В данном конкретном случае файлов может быть сколько угодно. Таким образом, ссылка будет вида http://yoursite/storage/qODmxc_G7dGm1NrG2KKtk93K6d_p2MqXr57nyNE= Чтобы декодировать строку и получить реальный путь к файлу внутри, нам нужно использовать функцию decryptF, часть кода контроллера, которая получает содержимое файла: И, наконец, чтобы заблокировать прямые ссылки, вам нужно (я использую nginx) написать примерно такую директиву: На этом все ;)
public static function decryptF($string)
{
$encryption_key = env('ENCRYPT_FILES_KEY'); // it's key from settings, use some string here...
assert(isset($string) === TRUE);
assert(isset($encryption_key) === TRUE);
$result = '';
$string = Helpers::base64url_decode($string);
for ($i = 0; $i < strlen($string); $i++)
{
$char = substr($string, $i, 1);
$keychar = substr($encryption_key, ($i % strlen($encryption_key)) - 1, 1);
$char = chr(ord($char) - ord($keychar));
$result .= $char;
}
return $result;
}
public static function encryptF($string)
{
$encryption_key = env('ENCRYPT_FILES_KEY');
assert(isset($string) === TRUE);
assert(isset($encryption_key) === TRUE);
$string = (string) $string;
$result = '';
for ($i = 0; $i < strlen($string); $i++)
{
$char = substr($string, $i, 1);
$keychar = substr($encryption_key, ($i % strlen($encryption_key)) - 1, 1);
$char = chr(ord($char) + ord($keychar));
$result .= $char;
}
return Helpers::base64url_encode($result);
}
Route::get('/storage/{link}', 'FileController@getFile');
public function upload($files, $poa_id) // recieve $request->file()
{
foreach ($files as $f) {
$f->move(storage_path('app/public/poadata/poa_'.$poa_id), $f->getClientOriginalName());
}
return redirect('poas.index');
}
$f = Storage::files('/public/poadata/poa_'.$poa->poa_id);
if (isset($f)):
foreach ($f as $file) {
echo '<a href=./storage/'.Helpers::encryptF('/poadata/poa_'.$poa->poa_id.'/'.pathinfo($file)
'filename'].'.'.pathinfo($file)['extension']).' target=_blank>' .pathinfo($file)['filename']. '
';
}
endif
public function getFile($link)
{
try {
$act = Helpers::decryptF($link);
$fullpath = "app/public/" . $act;
return response()->download(storage_path($fullpath), null, [], null);
} catch (FileNotFoundException $e) {
return $e->getCode();
}
}
location ~* ^/storage/poadata/ {
return 403;
}