CGI: использование GET вместо POST, когда клиент может использовать только строку URL - PullRequest
1 голос
/ 26 мая 2011

Моя ситуация такова, что у меня есть скрипт POST cgi, который генерирует и возвращает медиа-файл (mp3). Один из клиентов этого сценария хочет использовать объект медиаплеера iOS (MPMoviePlayer), который принимает только NSURL (в основном строку URL) в качестве входных данных. Проблема в том, что в iOS параметры POST не могут быть отправлены с использованием только NSURL. iOS, конечно, может отправлять запросы, используя другие объекты (NSURLRequest), но запуск сценария занимает некоторое время, поэтому нельзя выполнить запрос, сохранить файл на диск и затем передать файл в объект медиапроигрывателя.

Сначала я подумал, что, возможно, нам стоит перейти на GET, и хотя это не будет хорошим RESTful-дизайном, он не будет таким плохим, пока я создаю robots.txt. Но я нашел похожий вопрос по SO, который однозначно считает, что GET - плохая идея, если вы изменяете состояние сервера с помощью сценария cgi, даже если это облегчит доступ:

Использование GET вместо POST для удаления данных за аутентифицированными страницами

Я не вижу простого выхода из этого переписывания объекта медиаплеера. Кто-нибудь может предложить альтернативу изменению сценария на GET, все еще используя плеер на основе URL?

Самое страшное в использовании GET - это не хакеры безопасности / злоумышленники, потому что большинство этих проблем также влияют на POST. Я в основном беспокоюсь о новых «исправлениях» в роботах поисковых систем / etc, которые игнорируют robots.txt. Есть что-нибудь еще?

Также, если есть обоснование, почему GET может быть приемлемым здесь, мне также будет интересен этот ответ. Мне было интересно, не является ли проблема поисковой системы / бота здесь проблемой, потому что у нас не будет формы http, которая отправляет запрос GET куда-либо (поскольку приложение iOS сделает это из приложения), а сценарии cgi не определяют метод запроса, с которым они используются (хотя они могут обнаружить это и прервать.)

Ответы [ 4 ]

1 голос
/ 11 июня 2011

Я согласен, что POST является правильным методом HTTP в этом случае, когда клиентский запрос содержит параметры, которые приводят к созданию файла на сервере.Помимо того, что это хорошая практика, проблема с предварительной загрузкой браузера, с которой вы связались, является хорошим предупреждением о том, что может пойти не так (с тех пор Google отменил эту «функцию»).

Но, если вы собираетесьВперед с GET вместо переписывания с использованием POST, я дам несколько советов.

Что касается сканирования поисковых систем, это законная проблема.В последнее время я много работал со стандартом исключения роботов, и, по моему опыту, это хорошо соблюдаемый стандарт, которому следуют все законные сканеры, такие как поисковые системы.На данный момент ему более 15 лет, в основном без изменений, с очень простым синтаксисом.Хотя Google и компания сканируют все больше и больше вещей (новые типы файлов, внутри поисковых форм), я не могу себе представить, что они не подчиняются явному правилу Disallow.В любом случае, обязательно внедрите и протестируйте файл robots.txt для этих шаблонов URL, и это должно решить проблему поисковой системы.

Я не знаю, открываются ли эти URL-адреса пользователю каким-либо образом (адрес браузерапанель, ссылка на веб-страницу, которую они могут щелкнуть правой кнопкой мыши) или просто часть HTTP-трафика - но если это только последнее, вам не о чем беспокоиться.Глубокие URL-адреса, подобные этим, обычно индексируются, если они не переходят по ссылкам на вашем сайте, когда пользователи делятся ссылками по электронной почте, в Твиттере и т. Д. Если кто-то пишет в Твиттере ссылку и сканирует ее робот Google, Google подчиняется роботам.txt, а не индексировать его, но для вас все еще может быть проблема, что его можно найти в Twitter.Поэтому, насколько это возможно, заставляйте любые чувствительные URL работать только в фоновом режиме (я уверен, что 99,9% ваших пользователей не потрудятся прослушивать TCP, чтобы получить URL для обмена).

Что касается смягчения последствийдругие проблемы с GET, я бы предложил использовать nonce как часть вашего GET URL вместе с ключом сеанса.Это довольно стандартная вещь в веб-приложениях для защиты от CSRF, и она сделает эти GET-URL доступными для использования только один раз клиентским сеансом (если это слишком ограничительно, вы можете сделать их доступными для сеанса дольше ... используйте времяна основе хэша вместо одноразового номера).Когда срок действия одноразового номера истек, верните перенаправление 404 или 30X.

Еще можно сделать, вместо того, чтобы CGI возвращал поток файлов .mp3 напрямую, чтобы он перенаправил HTTP на второй URL, которыйвозвращает файл.В зависимости от того, хотите ли вы, чтобы этот второй URL был «общедоступным», вы можете использовать постоянный (301) или временный (302/303) код ответа.Поисковые системы не будут индексировать исходный URL-адрес GET, так как это приведет к перенаправлению и не будет сохраняться в адресной строке браузера для копирования / вставки пользователем.

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

При предварительной выборке ... спецификации HTML переходят к выборочной предварительной выборке ссылок с type="prefetch" (в настоящее время *)1021 * выполняет это в теге link, но нет эквивалента, указывающего, что тег a может / должен быть предварительно выбран), а не в поведении «предварительная выборка по умолчанию для всего».Связанная проблема заключается в том, что предварительная выборка также может производиться прокси-серверами (например, Squid офисной сети или мобильными браузерами, такими как Opera Mini, которые используют прокси-сервер для получения и повторного сжатия изображений), но я не знаю ни одного, который в настоящее времясделай это.Итак, я не думаю, что у вас есть что-то, что действительно беспокоит вас в этой области, но если вы хотите быть параноиком по этому поводу, выход состоит в том, чтобы следовать правилам и просто использовать POST при изменении состояния сервера.

1 голос
/ 10 июня 2011

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

  1. если mp3 можно использовать повторно, приложение должно сгенерировать mp3 заранее или по запросу, а затем кэшировать результат.Таким образом, последующие запросы GET просто обслуживают данные, что является правильным использованием GET.

  2. , если mp3 является пользовательским для данного экземпляра загрузки, тогда запрос POST является более подходящим,поскольку это запрос к системе генерировать ресурс в определенном контексте.Этот контекст предоставляется данными в POST.Имейте в виду, что REST не религиозен в отношении значения POST - вы можете использовать его, чтобы делать множество подобных вещей, не выходя за рамки модели.

Если вы обеспокоены, вместо этогоЧто касается загрузки роботами, то есть несколько хитростей, которые вы можете использовать:

  1. Ограничение доступа к ресурсу по IP.Многократные запросы к ресурсу могут быть ограничены одним каждую минуту, или что-то, что кажется подходящим.Это даст вам некоторую защиту от атак типа «отказ в обслуживании».

  2. Заблокируйте доступ к ресурсу для известных роботов.Существуют списки IP-адресов общих индексаторов, и вы можете использовать их для возврата 403 (запрещенных) ответов на GET вашего ресурса.

  3. Фильтрация доступа к ресурсу на основе HTTP-запросазаголовки.Например, вы можете посмотреть на User-Agent и убедиться, что это один из ваших «поддерживаемых» браузеров.Это, вероятно, наименее целесообразно.

Надеюсь, это поможет.

0 голосов
/ 09 июня 2011

GET должно быть в порядке.Вам не нужно слепо следовать спецификации, написанной для общего пользования.В вашей ситуации вам будет гораздо проще использовать GET - так почему бы не использовать?

0 голосов
/ 26 мая 2011

GET должно быть в порядке.

Важной частью здесь является то, что клиент не запрашивает изменение состояния сервера.

См. Спецификацию :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...