Indy TIdHTTP, по-видимому, отсутствует файл cookie сервера при почтовом запросе?

У меня Indy 10.6.2.5366 и Delphi Tokyo 10.2 с обновлением 3.

В ответ на HTTPS POST CookieManager сообщает, что файлов cookie нет, но когда я делаю тот же запрос в почтальоне, в ответе появляется файл cookie с именем «ROUTEID».

но когда я делаю тот же запрос в Delphi, файл cookie «ROUTEID» отсутствует.

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

Должно быть, я делаю что-то не так, потому что в этом другом посте Реми говорит, что TCookieManager был полностью переписан с нуля, но что мне не хватает?

Я заметил, что почтальон показывает 10 заголовков в ответе, а Delphi показывает только 8 в TIdHTTP.Response.RawHeaders

Я знаю, что код ответа моего запроса 401, но даже при несанкционированной ошибке в ответе присутствует куки.

наконец, вот мой код:

procedure TestMethod(AUrl, ABody: string);
var
  HTTP: TIdHTTP;
  SSL: TIdSSLIOHandlerSocketOpenSSL;
  LStreamRequestBody: TStringStream;
  LReturnBody: string;
  LCookieList: TIdCookieList;
  n: Integer;
begin

  HTTP := TIdHTTP.Create(nil);
  SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  LStreamRequestBody := TStringStream.Create(ABody, TEncoding.UTF8);
  try
    IdOpenSSLSetLibPath(Utils.Global.SSLLibPath);

    SSL.SSLOptions.Method := sslvSSLv23;
    SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
    SSL.SSLOptions.Method := sslvSSLv23;

    HTTP.IOHandler := SSL;
    HTTP.Response.ContentType := 'application/json;charset=utf-8';
    HTTP.Request.CustomHeaders.FoldLines := True;
    HTTP.Request.Accept := '*/*';
    HTTP.Request.ContentType := 'application/json';
    HTTP.Request.Connection := 'keep-alive';
    HTTP.Request.AcceptEncoding := 'gzip, deflate, br';
    HTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';

    HTTP.CookieManager := TIdCookieManager.Create(nil);
    HTTP.AllowCookies := True;
    HTTP.HandleRedirects := True;

    try
      LReturnBody := HTTP.Post(AUrl, LStreamRequestBody);
    Except
      on e: EIdHTTPProtocolException do
      begin
        LCookieList := HTTP.CookieManager.CookieCollection.LockCookieList(caRead);
        try
          for n := 0 to LCookieList.Count - 1 do
          begin

          end;
        finally
          HTTP.CookieManager.CookieCollection.UnlockCookieList(caRead);
        end;
      end;
    end;
  finally
    LStreamRequestBody.Free;
    HTTP.Free;
    SSL.Free;
  end;
end;

«У меня Indy 10.6.2.5366» — это довольно старая версия. Текущая версия — 10.6.3.3. Вам следует рассмотреть возможность обновления.

Remy Lebeau 04.08.2024 18:46

я обновлю свой Indy, спасибо!

Rebelss 04.08.2024 22:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В ответ на HTTPS POST CookieManager сообщает, что файлов cookie нет, но когда я делаю тот же запрос в почтальоне, в ответе появляется файл cookie с именем «ROUTEID»... но когда я делаю точно такой же запрос в Delphi, нет файла cookie «ROUTEID».

Тогда проблема не в самом Инди. Сервер изначально не отправляет файлы cookie.

Я заметил, что почтальон показывает 10 заголовков в ответе, но Delphi показывает только 8 в TIdHTTP.Response.RawHeaders.

Это означает, что сервер отправляет разные ответы разным пользовательским агентам. Смотрите этот вопрос , на который я ответил буквально вчера, который страдал от подобной проблемы. Но в двух словах:

Многие серверы чувствительны к запрашивающему агенту и отправляют разные данные разным агентам. Такие серверы нередко отклоняют/не распознают значение Indy по умолчанию User-Agent.

...

Когда вы сравниваете запросы Curl [или, в данном случае, Postman] с другими HTTP-библиотеками, вы всегда должны стремиться к тому, чтобы запросы были как можно более идентичными, чтобы исключить любые возможные различия, которые могут сбить с толку серверы. А когда между похожими запросами существуют различия в поведении, обычно виноват User-Agent [заголовок запроса].

Я вижу, вы устанавливаете для свойства TIdHTTP.Request.UserAgent значение, имитирующее Firefox. Возникнет ли у вас та же проблема, если вместо этого вы настроите имитацию Почтальона? Я считаю, что значение User-Agent Postman по умолчанию — это что-то вроде PostmanRuntime/<version>. Возникнет ли у вас та же проблема, если вы настроите Postman на использование того же значения Firefox User-Agent, что и TIdHTTP?


Кстати, это связано не с вашей проблемой с файлами cookie, а с представленным вами кодом в целом:

  • вам не следует вызывать IdOpenSSLSetLibPath() при каждом HTTP-запросе. Вызовите его один раз, желательно при запуске приложения.

  • не используйте свойства SSLOptions.Method и SSLOptions.SSLVersions SSLIOHandler вместе. Они являются взаимоисключающими, установка одного обновляет другой. Установив Method на sslvSSLv23, вы включаете SSL v2–v3 в дополнение к TLS v1.0–1.2. Больше не включайте SSL. Остановитесь только на свойстве SSLVersions.

  • не устанавливайте свойство TIdHTTP.Response.ContentType при отправке запроса. Это просто бесполезно.

  • свойство TIdHTTP.Request.CustomHeaders.FoldLines должно иметь значение False, поскольку протокол HTTP больше не поддерживает свертывание заголовков, начиная с RFC 7230.

  • не устанавливайте свойство TIdHTTP.Request.AcceptEncoding вручную, если вы не готовы декодировать необработанное тело ответа вручную. Indy изначально поддерживает сжатие gzip и deflate через свойство TIdHTTP.Compressor, но в настоящее время не поддерживает br. Вы даете серверу разрешение на сжатие ответа таким образом, чтобы TIdHTTP не могло быть распаковано автоматически (например, на вашем снимке экрана показано, что ответ сжат с помощью gzip). Правильный подход — включить Compressor и позволить TIdHTTP управлять AcceptEncoding за вас, исходя из реальных возможностей компрессора.

  • вы сливаете объект TIdCookieManager. TIdHTTP не становится владельцем предоставленного пользователем CookieManager. Если вы его не предоставите, TIdHTTP просто создаст его внутри компании и возьмет на себя ответственность за него.

Спасибо, Реми, ты совершенно прав, когда я меняю User-Agent на PostmanRuntime/7.40.0, файлы cookie появляются в rawHeaders, также спасибо за обзор кода, я внесу изменения, как ты сказал!

Rebelss 04.08.2024 22:42

Другие вопросы по теме