Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
gil707
7 лет назад

Сокрытие прямых ссылок на файлы в 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));
}

Затем пишем необходимые функции кодирования / декодирования


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);
}

Чтобы поймать URL-адреса в браузере, нам нужно написать маршрут. Файлы сохраняются в стандартном хранилище и в подпапках Laravel.


Route::get('/storage/{link}', 'FileController@getFile');

Итак, если мы хотим сохранить файлы из формы, мы должны написать функцию в нужном нам контроллере, я сохраняю файлы в 'app/public/poadata'


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

Таким образом, ссылка будет вида http://yoursite/storage/qODmxc_G7dGm1NrG2KKtk93K6d_p2MqXr57nyNE=

Чтобы декодировать строку и получить реальный путь к файлу внутри, нам нужно использовать функцию decryptF, часть кода контроллера, которая получает содержимое файла:

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();
}
}

И, наконец, чтобы заблокировать прямые ссылки, вам нужно (я использую nginx) написать примерно такую директиву:


location ~* ^/storage/poadata/ {
return 403;
}

На этом все ;)

3
0.000 GOLOS
На Golos с July 2017
Комментарии (0)
Сортировать по:
Сначала старые