HTTP GET с телом запроса

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

Это довольно распространенный тип аутентификации, используемый банками.

Скажите, что вы обращаетесь на свой банковский сайт через example-isp.com. В первый раз, когда вы там, вас попросят ввести свой пароль, а также дополнительную проверку подлинности. После того, как вы прошли, банк знает, что пользователь «thatisvaliant» аутентифицирован для доступа к сайту через example-isp.com.

В будущем он не будет запрашивать дополнительную аутентификацию (кроме вашего пароля ), когда вы обращаетесь к сайту через example-isp.com. Если вы попытаетесь получить доступ к банку через another-isp.com, банк снова повторит ту же процедуру.

Итак, чтобы определить, какой идентификатор банка является вашим интернет-провайдером и / или netblock, на основе вашего Айпи адрес. Очевидно, что не каждый пользователь вашего интернет-провайдера - это то, почему банк все еще спрашивает вас о вашем пароле.

У вас когда-либо был звонок по кредитной карте, чтобы убедиться, что все в порядке, когда вы используете кредитную карту в другой стране? Та же концепция.

1756
задан Honey 22 October 2018 в 04:12
поделиться

7 ответов

Комментарий Роя Филдинга о включении тела в запрос GET .

Да. Другими словами, любое сообщение HTTP-запроса может содержать тело сообщения и, следовательно, должен анализировать сообщения с учетом этого. Однако семантика сервера для GET ограничена таким образом, что тело, если есть, не имеет смыслового значения для запроса. Требования на синтаксический анализ отделены от требований к семантике метода.

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

Это часть многоуровневого дизайна HTTP / 1.1, который станет очистите снова, как только спецификация будет разделена (работа в процессе).

.... Roy

Да, вы можете отправить тело запроса с помощью GET, но это не должно иметь никакого значения. Если вы придаете ему смысл, анализируя его на сервере и изменяя свой ответ на основе его содержимого , то вы игнорируете эту рекомендацию в спецификации HTTP / 1.1, раздел 4.3 :

]

[...] если метод запроса не включает определенную семантику для тела объекта, тогда message-body СЛЕДУЕТ игнорировать при обработке запроса.

И описание метода GET в спецификации HTTP / 1.1, раздел 9.3 :

Метод GET означает получить любую информацию ([...]), идентифицированную Request-URI.

, в котором указано, что тело запроса не является частью идентификации ресурса в запросе GET, а является только URI запроса.

Обновление RFC2616, обозначенный как «спецификация HTTP / 1.1», теперь устарел. В 2014 году его заменили RFC 7230-7237. Цитата "СЛЕДУЕТ игнорировать тело сообщения при обработке запроса" была удалена. Теперь просто «Формирование сообщения запроса не зависит от семантики метода, даже если метод не определяет какое-либо использование тела сообщения» 2-я цитата «Метод GET означает получение любой информации ... идентифицированной Request-URI» был удален. - Из комментария

1568
ответ дан 22 November 2019 в 20:02
поделиться

Даже если популярное использование инструмента это, как цитируется часто на этой странице, я думаю, что это - все еще вполне плохая идея, будучи слишком экзотичным, несмотря на не запрещенный спецификацией.

Много промежуточных инфраструктур могут просто отклонить такие запросы.

примером, забудьте об использовании некоторых доступных CDN перед Вашим веб-сайтом, как этот один :

, Если средство просмотра GET запрос включает тело, CloudFront возвращает Код состояния HTTP 403 (Запрещенный) средству просмотра.

И да, Ваши клиентские библиотеки не могут также поддерживать испускание таких запросов, как сообщается в этом комментарий .

0
ответ дан Frédéric 4 October 2019 в 07:25
поделиться

Я использую платформу Spring RestTemplate в моей клиентской программе и в серверной стороне, я определил ПОЛУЧИТЬ запрос с телом Json. Моя основная цель совпадает с Вашей: когда запрос имеет многочисленные параметры, помещение их в теле кажется более опрятным, чем помещение их в длительной строке URI. Да?

, Но, к сожалению, это не работает! Серверная сторона выдала следующее исключение:

org.springframework.http.converter. HttpMessageNotReadableException: Необходимое тело запроса отсутствует...

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

я проследил в RestTemplate.exchange () метод и нашел следующее:

// SimpleClientHttpRequestFactory.class
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
    ...
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
        ...
        if (!"POST".equals(httpMethod) && !"PUT".equals(httpMethod) && !"PATCH".equals(httpMethod) && !"DELETE".equals(httpMethod)) {
            connection.setDoOutput(false);
        } else {
            connection.setDoOutput(true);
        }
        ...
    }
}

// SimpleBufferingClientHttpRequest.class
final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttpRequest {
    ...
    protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
        ...
        if (this.connection.getDoOutput() && this.outputStreaming) {
            this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
        }

        this.connection.connect();
        if (this.connection.getDoOutput()) {
            FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
        } else {
            this.connection.getResponseCode();
        }
        ...
    }
}

заметьте, что в executeInternal () метод, входной параметр 'bufferedOutput' содержит тело сообщения, обеспеченное моим кодом. Я видел его через отладчик.

Однако из-за prepareConnection (), getDoOutput () в executeInternal () всегда возвращает false, который, в свою очередь, делает bufferedOutput полностью проигнорированным! Это не копируется в поток вывода.

, Следовательно, моя программа сервера не получила тела сообщения и выдала то исключение.

Это - пример о RestTemplate платформы Spring. Дело в том, что, даже если тело сообщения больше не запрещается спецификацией HTTP, некоторый клиент или библиотеки сервера или платформы могли бы все еще выполнить старую спецификацию и отклонить тело сообщения от ПОЛУЧИТЬ запроса.

-1
ответ дан 22 November 2019 в 20:02
поделиться

То, что вы пытаетесь достичь, долгое время делалось гораздо более распространенным методом, который не полагается на использование полезной нагрузки с GET.

Вы можете просто создайте свой конкретный поисковый медиатип или, если вы хотите быть более RESTful, используйте что-то вроде OpenSearch и отправьте запрос на URI, указанный сервером, например / search. Затем сервер может сгенерировать результат поиска или создать окончательный URI и перенаправить с использованием 303.

Это дает преимущество использования традиционного метода PRG, помогает кэшировать промежуточные результаты, кэшировать результаты и т. Д.

Тем не менее, URI являются так или иначе закодированы для всего, что не является ASCII, как и application / x-www-form-urlencoded и multipart / form-data. Я'

30
ответ дан 22 November 2019 в 20:02
поделиться

Я бы этого не советовал, это идет вразрез со стандартной практикой и не дает так много взамен. Вы хотите сохранить тело для содержания, а не для вариантов.

5
ответ дан 22 November 2019 в 20:02
поделиться

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

140
ответ дан 22 November 2019 в 20:02
поделиться

Хотя вы можете сделать это, поскольку это явно не исключается спецификацией HTTP, я бы посоветовал избегать этого просто потому, что люди не ожидают, что что-то будет работать туда. В цепочке HTTP-запросов есть много этапов, и хотя они «в основном» соответствуют спецификации HTTP, единственное, в чем вы уверены, - это то, что они будут вести себя так, как традиционно используются веб-браузерами. (Я имею в виду такие вещи, как прозрачные прокси-серверы, ускорители, инструменты A / V и т. Д.)

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

Однако, если у вас есть веская причина, дерзайте.

272
ответ дан 22 November 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: