Сокрытие пути к файлам.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
xor
Сообщения: 2
Зарегистрирован: 2018.02.08, 18:25

Сокрытие пути к файлам.

Сообщение xor »

На сайте есть закрытый раздел в котором нужно отображать таблицу с данными клиентов. В таблице есть поле - "скан паспорта", там надо отображть картинку со сканом пасспорта, в БД хранится полный путь к файлу, вида "/var/www/Project/storage/passport.jpg".
Можно ли как-то отобразить картинки на определенной странице, но при этом защитить их от просмотра из любых других мест?

Пока думаю над тем что бы написать отдельный метод который будет проверять rbac-роль и если у пользователя есть права на просмотр, копировать нужный файл в какое нибудь временное хранилище и уже не него давать ссылку. Но это выглядит очень громоздким решением.
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

Можно попробовать такой вариант:

Создаём алиас для папки storage
Для advanced папка storage на уровне с frontend и backend
/common/config/bootstrap.php

Код: Выделить всё

//common/config/bootstrap.php
Yii::setAlias('@storage', dirname(dirname(__DIR__)) . '/storage');
Виджет:

Код: Выделить всё

<?php

namespace app\widgets;

use yii\bootstrap\Widget;
use yii\helpers\Html;

/**
 * Class ImageWidget
 * @package app\widgets
 */
class ImageWidget extends Widget
{
    /**
     * @var string
     */
    public $path;
    /**
     * @var string
     */
    public $type;
    /**
     * @var array
     */
    public $imageOptions = [];

    public function init()
    {
        parent::init();
    }

    public function run()
    {
        if ($image = $this->getImage()) {
            echo Html::img($image, $this->imageOptions);
        }
    }

    /**
     * @return bool|string
     */
    public function getImage()
    {
        $this->type = $this->type ? $this->type : $this->getType();
        return $this->base64_encode_image($this->path, $this->type);
    }

    /**
     * @param $filename string
     * @param $filetype string
     * @return string|bool
     */
    public function base64_encode_image($filename, $filetype)
    {
        if ($filename) {
            $imgbinary = fread(fopen($filename, "r"), filesize($filename));
            return 'data:image/' . $filetype . ';base64,' . base64_encode($imgbinary);
        }
        return false;
    }

    /**
     * @return string
     */
    protected function getType()
    {
        $info = new \SplFileInfo($this->path);
        return $info->getExtension();
    }
}
Использование:

Код: Выделить всё

<?= \app\widgets\ImageWidget::widget([
    'path' => Yii::getAlias('@storage/pasport.jpg'),
]) ?>
Выводить только тем, у кого есть права на просмотр. Готово!
Последний раз редактировалось Dominus 2018.02.09, 16:27, всего редактировалось 1 раз.
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Сокрытие пути к файлам.

Сообщение Nex-Otaku »

Такой вопрос задавали.

Вот мой велосипед viewtopic.php?p=228610#p228610
Это в теории, на практике не пробовал.

Вот модуль для nginx, который предложил chesar: viewtopic.php?f=19&t=45815
По сути, нужно подключить модуль и сделать для него небольшой PHP-скрипт, который проверяет статус пользователя.
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Сокрытие пути к файлам.

Сообщение Nex-Otaku »

Dominus писал(а): 2018.02.09, 09:48 $imgbinary = fread(fopen($filename, "r"), filesize($filename));
Мне кажется, читать файлы картинок в память PHP, как-то не комильфо )

Но как быстрый честный костыль, почему бы и нет )
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

Nex-Otaku писал(а): 2018.02.09, 09:59
Dominus писал(а): 2018.02.09, 09:48 $imgbinary = fread(fopen($filename, "r"), filesize($filename));
Мне кажется, читать файлы картинок в память PHP, как-то не комильфо )

Но как быстрый честный костыль, почему бы и нет )
Ну в общем то это пример из манов php: http://php.net/manual/ru/function.base6 ... php#105200
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

Можно упростить.
Виджет:

Код: Выделить всё

<?php

namespace app\widgets;

use yii\bootstrap\Widget;
use yii\helpers\Html;

/**
 * Class ImageWidget
 * @package app\widgets
 */
class ImageWidget extends Widget
{
    /**
     * @var string
     */
    public $path;
    /**
     * @var array
     */
    public $imageOptions = [];

    public function init()
    {
        parent::init();
    }

    public function run()
    {
        if ($image = $this->getImage($this->path)) {
            echo Html::img($image, $this->imageOptions);
        }
    }

    /**
     * @param string $filename
     * @return bool|string
     */
    public function getImage($filename)
    {
        if ($filename) {
            $imageData = base64_encode(file_get_contents($filename));
            return 'data: ' . mime_content_type($filename) . ';base64,' . $imageData;
        }
        return false;
    }
}
Вывод виджета:

Код: Выделить всё

<div class="col-lg-4">
    <?= \app\widgets\ImageWidget::widget([
        'path' => Yii::getAlias('@storage/pasport.jpg'),
        'imageOptions' => [
            'class' => 'img-responsive img-thumbnail',
        ],
    ]) ?>
</div>
Последний раз редактировалось Dominus 2018.02.09, 16:26, всего редактировалось 1 раз.
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
xor
Сообщения: 2
Зарегистрирован: 2018.02.08, 18:25

Re: Сокрытие пути к файлам.

Сообщение xor »

Большое спасибо, ваш виджет прекрасно решает мою проблему. Большой нагрузки на сервер не планируется, поэтому чтение картинок проблем вызвать не должно.
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Сокрытие пути к файлам.

Сообщение urichalex »

[offtop]
Часто вижу такую реализацию

Код: Выделить всё

Url::to('@storage') . '/pasport.jpg'
Во-первых Url::to() предназначен для формирования url на основе правил, тут надо бы использовать Yii::getAlias()
А во вторых, зачем конкатинировать? Ведь в винде этот путь превратится в c:\path\to\storage/passport.jpeg
Ведь правильнее использовать

Код: Выделить всё

Yii::getAlias('@storage/pasport.jpg');
[/offtop]
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

urichalex писал(а): 2018.02.09, 14:21 [offtop]
Часто вижу такую реализацию

Код: Выделить всё

Url::to('@storage') . '/pasport.jpg'
Во-первых Url::to() предназначен для формирования url на основе правил, тут надо бы использовать Yii::getAlias()
А во вторых, зачем конкатинировать? Ведь в винде этот путь превратится в c:\path\to\storage/passport.jpeg
Ведь правильнее использовать

Код: Выделить всё

Yii::getAlias('@storage/pasport.jpg');
[/offtop]
Ну по первому, тут показано что алиасы в Url::to() использовать можно http://rmcreative.ru/blog/post/yii2-izm ... bote-s-url и тут http://www.yiiframework.com/doc-2.0/gui ... r-url.html
По второму, у меня винда, путь превращается да, но это не влияет на работу, отрабатывает всё корректно.
Критично было если бы так:

Код: Выделить всё

Url::to('@storage') . '\pasport.jpg'
проблема была бы с таким путём в Linux.

А так, можно еще:

Код: Выделить всё

Url::to('@storage/pasport.jpg');
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Сокрытие пути к файлам.

Сообщение urichalex »

Dominus писал(а): 2018.02.09, 14:27 Ну по первому, тут показано что алиасы в Url::to() использовать можно http://rmcreative.ru/blog/post/yii2-izm ... bote-s-url и тут http://www.yiiframework.com/doc-2.0/gui ... r-url.html
Url::to() так же сначала преобразует через Yii::getAlias():
https://github.com/yiisoft/yii2/blob/ma ... l.php#L217
Но перед этим проверяет на массив и после этого кучу проверок.
Dominus писал(а): 2018.02.09, 14:27 По второму, у меня винда, путь превращается да, но это не влияет на работу, отрабатывает всё корректно.
Критично было если бы так:

Код: Выделить всё

Url::to('@storage') . '\pasport.jpg'
проблема была бы с таким путём в Linux.
По тому, что разрабы напряглись и нарисовали костыль для таких случаев. А использование лишнего костыля - лишнее ресурсы (ой да мой бложик никто не посещает мне плявать на ресурсы)
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

Сперва понял что вы имели ввиду то что нельзя использовать алиасы в Url::to().
Спасибо, поправил на:

Код: Выделить всё

Yii::getAlias('@storage/pasport.jpg')
viewtopic.php?f=19&t=46554#p231990
viewtopic.php?f=19&t=46554&p=232021#p231995

P.S.
Windows

Код: Выделить всё

var_dump(Yii::getAlias('@storage/pasport.jpg'));

string 'E:\OpenServer\domains\...\public_html/storage/pasport.jpg' (length=75)
Но на работу в Windows этот путь никоим образом не влияет, отрабатывает корректно.

Можно еще использовать DIRECTORY_SEPARATOR

Код: Выделить всё

Yii::setAlias('@storage', dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'storage');

Код: Выделить всё

var_dump(Yii::getAlias('@storage') . DIRECTORY_SEPARATOR . 'pasport.jpg');

string 'E:\OpenServer\domains\...\public_html\storage\pasport.jpg' (length=75)
http://rmcreative.ru/blog/post/director ... ator-v-php
Последний раз редактировалось Dominus 2018.02.09, 17:49, всего редактировалось 3 раза.
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Сокрытие пути к файлам.

Сообщение Nerf »

Можете еще в сторону хедеров X-Sendfile(Apache) и X-Accel-Redirect(Nginx) посмотреть. Ваш обработчик на php будет решать отдавать или нет, а веб-сервер отдавать статику (недоступную напрямую).
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Сокрытие пути к файлам.

Сообщение Nex-Otaku »

Dominus писал(а): 2018.02.09, 10:13
Nex-Otaku писал(а): 2018.02.09, 09:59 Мне кажется, читать файлы картинок в память PHP, как-то не комильфо )

Но как быстрый честный костыль, почему бы и нет )
Ну в общем то это пример из манов php: http://php.net/manual/ru/function.base6 ... php#105200
Из пользовательских комментариев к манам, всё-таки разница есть )
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Сокрытие пути к файлам.

Сообщение Dominus »

Ну так я и не говорил что это рекомендация)) Ну а так, ели допускают код на оф сайте php, доверие к таким комментам есть, потом система одобрения там работает, как она показывает, код не плох)
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Ответить