Silverstripe — Google выбирает ссылки только на странице для зарегистрированных пользователей.

У меня есть этот сайт, построенный на серебряной полосе, у меня есть страницы участников только для участников.

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

Я заметил, что когда он находится на странице участников, вы должны войти в систему, URL-адрес www.mysite.com/members/
Однако, когда я нажимаю на одну из ссылок на этой странице, URL-адрес меняется на www.mysite/ активы/Загрузки/участники/книги/myfirstbook.pdf

Пока кто-то выполняет поиск в Google по названию книги, например myfirstbook и mysite, на странице участников будет отображаться ссылка в формате pdf, и вы можете щелкнуть по ней и просмотреть содержимое в формате pdf.

Как я могу заблокировать нечленов для просмотра этих файлов PDF? Я пробовал robot.txt и модель безопасных файлов, они не работали. Пожалуйста помоги. Спасибо!


person grumpypanda    schedule 24.05.2013    source источник


Ответы (2)


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

По сути, я создал папку в AssetAdmin с именем FilteredDownload, и любое место в этой папке будет проходить через фильтрацию (форма и т. д.).

У меня было это правило в .htaccess (которое можно было отредактировать...), перенаправляя любой запрос к любому из этих файлов на Downloader_Controller

RewriteCond %{REQUEST_URI} /assets/FilteredDownload [NC]
RewriteCond %{REQUEST_URI} !/assets_temp [NC]
RewriteCond %{REQUEST_FILENAME} \.(pdf|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$ [NC]
RewriteRule .* downloader?file=%{REQUEST_FILENAME}&%{QUERY_STRING} [L,NC]

Затем я просто использовал этот контроллер для сервера формы и файлов.

В вашем случае вы можете просто использовать этот контроллер, чтобы проверить, вошел ли посетитель в систему, и если не перенаправить его/ее на страницу входа, запретить доступ или что-то еще...

Не совсем то же самое, что и ваша проблема, но я мог легко увидеть, как это адаптировано?


ИЗМЕНИТЬ

Лучше посмотрел на это и, основываясь на вышеизложенном, похоже, что это работает:

Серебряная полоса 3+

Добавляем это к .htaccess:

RewriteCond %{REQUEST_URI} /assets/MembersOnly [NC]
RewriteCond %{REQUEST_FILENAME} \.(pdf|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$ [NC]
RewriteRule .* filedownloadpermission?file=%{REQUEST_FILENAME}&%{QUERY_STRING} [L,NC]

Таким образом, каждый файл, загруженный под /assets/MembersOnly, перед загрузкой сначала будет проходить через /filedownloadpermission.

Определите правило Director в config.yml:

---
Name: myroutes
After: framework/routes#coreroutes
---
Director:
  rules:
    'filedownloadpermission/$Action/$ID/$Name': 'FileDownloadPermission_controller'

Затем наш контроллер FileDownloadPermission_controller.php, который будет проверять наличие разрешений перед подачей файла или нет:

<?php

class FileDownloadPermission_controller extends ContentController
{
    private static $allowed_actions = array (
    );

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

        if( !$member = Member::currentUser() )
        {
                  Security::permissionFailure();
        }    
    }

    public function index()
    {
        $file = $this->request->getVar('file');
        $fileAssetPath = substr($file, stripos($file, 'assets'));    
                $fileObj = File::get()->filter(array('Filename' => $fileAssetPath))->first();

                if ( $fileObj )
                {
                   $data = file_get_contents( $fileObj->getFullPath() );
                   $name = $fileObj->getFilename();
                   $response = SS_HTTPRequest::send_file($data, $name);
                   return $response;
                }
                else {
                   //Return 404 or whatever...
                }
    }
}

Это на самом деле написано для SilverStripe 3.1, но может быть легко адаптировано для 2.4:

  • $allowed_actions должно быть public
  • Director правило будет добавлено к _config.php вместо него
  • Обновить File::get()... до DataObject::get...

Итак, это дает нам SilverStripe 2.4+

in _config.php

Director::AddRules(100, array('filedownloadpermission/$Action/$ID/$OtherID' => 'FileDownloadPermission_controller'));

и наш контроллер FileDownloadPermission_controller.php:

<?php

class FileDownloadPermission_controller extends ContentController
{
    static $allowed_actions = array (
    );

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

        if( !$member = Member::currentUser() )
        {
                  Security::permissionFailure();
        }    
    }

    public function index()
    {
        $file = $this->request->getVar('file');
        $fileAssetPath = substr($file, stripos($file, 'assets')); 
                $fileObj = DataObject::get(
                                 "File",
                                 "Filename = '".$fileAssetPath."'",
                                 null, null, "1");

                if ( $fileObj )
                {
                    $fileObj = $fileObj->shift();

                    $data = file_get_contents( $fileObj->getFullPath() );
                    $name = $fileObj->getFilename();
                    $response = SS_HTTPRequest::send_file($data, $name);
                    return $response;
                }
                else {
                    //Return 404 or whatever...
                }
    }
}

Это довольно быстрое решение и, вероятно, может быть немного лучше, но должно дать вам хорошее начало_

person colymba    schedule 24.05.2013
comment
Да, ваш Director::addRules верен. Это нужно добавить в mysite/_config.php. И создайте файл FileDownloadPermission_controller.php в разделе mysite/code (хорошее место для его хранения). Не забудьте очистить кеш с помощью ?flush=all - person colymba; 27.05.2013
comment
Спасибо, Colymba, да, это то, что я сделал, теперь у меня ошибка сервера, показывающая мне страницу с ошибкой, и она выводит меня из страницы участников. Как вы думаете, где я должен искать проблему здесь? Есть ли еще места, которые мне нужно изменить в вашем коде или в коде сайта, чтобы он работал? Спасибо. - person grumpypanda; 27.05.2013
comment
Что за ошибка сервера? 500? 404? У вас есть журнал? У меня нет установки SS2.4, которую я мог бы протестировать, поэтому трудно сказать. Сначала посмотрим, какую ошибку вы получите. - person colymba; 27.05.2013
comment
Наконец-то удалось протестировать это в SS2.4, и было несколько дополнительных вещей, которые нужно понизить, извините. В основном DataObject::get()... Я обновил ответ полным кодом SS2.4. Обновите свои файлы и посмотрите, как все пойдет. - person colymba; 27.05.2013
comment
Ты легенда, спасибо, это работает. Еще один вопрос: есть ли способ сделать так, чтобы PDF-файлы не загружались, а отображались на другой вкладке после перехода по ссылке? Или его нужно скачать, чтобы этот метод работал. Я очень ценю вашу помощь, спасибо! - person grumpypanda; 28.05.2013
comment
рад, что это сработало. если вы можете пометить ответ как принятый, это поможет и другим. Чтобы вывести файл напрямую, вам может потребоваться изменить SS_HTTPRequest::send_file на что-то другое, что выводит файл прямо в буфер, например fpassthru. - person colymba; 28.05.2013
comment
Да, я обязательно выберу ваш ответ, так как вы спасли мой день, спасибо. Прежде чем я его закрою, как бы вы использовали что-то вроде fpassthru вместо SS_HTTPRequest::send_file в Silverstripe? (Я использовал его, но страница PDF стала пустой). Было бы здорово открыть эти PDF-файлы на другой вкладке, а не загружать, если бы вы могли помочь мне в этом. Большое спасибо, я ценю это. - person grumpypanda; 28.05.2013
comment
Обратите внимание, что это, вероятно, будет зависеть от конфигурации браузера пользователя, отображается ли файл или загружается. Хотя я не использовал fpassthru, вот несколько примеров: php.net/manual/ en/function.fpassthru.php / stackoverflow.com/questions/1597732/, а также может работать файл чтения, возможно, php.net/manual/en/function.readfile.php . вам, вероятно, придется правильно установить заголовок... извините, я не могу больше помочь в этом.. - person colymba; 28.05.2013
comment
Все хорошо, большое спасибо за вашу помощь, вы были великолепны. Я надеюсь, что однажды я смогу, как и вы, помочь другим, большое спасибо. - person grumpypanda; 28.05.2013

Для применения robot.txt потребуется некоторое время. Однако на самом деле он ничего не защищает, а просто удаляет из индекса поисковой системы.

Какой безопасный файловый модуль вы пробовали? https://github.com/hamishcampbell/silverstripe-securefiles В чем конкретно проблема с "он не не работает"?

Это будет работать только с SilverStripe 2.x. Вам нужно решение для 3.x?

person xeraa    schedule 24.05.2013
comment
Спасибо, Xeraa, да, я попробовал вашу ссылку на безопасный файловый модуль, проблема в том, что сайт использует «KickAssets» для загрузки всех файлов для папки с активами, мне трудно реализовать оба вместе. Не могли бы вы научить меня, как объединить защищенные файлы и кикактивы вместе? Большое спасибо. - person grumpypanda; 24.05.2013
comment
Кстати, я использую SS 2.4.5, так что это не должно быть проблемой. Считаете ли вы, что я должен использовать robot.txt, а также «защищенные файлы» для моей цели? Если бы вы могли дать мне некоторую помощь / советы о том, как объединить защищенные файлы и кикактивы, я был бы очень признателен. Спасибо. - person grumpypanda; 24.05.2013
comment
Не думаю, что с KickAssets будут проблемы — это просто новый бэкенд для управления файлами, но внутреннюю структуру он не меняет. Для версии 2.4 я бы выбрал модуль Хэмиша (вероятно, пропустив KickAssets для начала), и вам не понадобится специальный файл robots.txt. - person xeraa; 27.05.2013