• 0
GoldenEalge

[THttpClient] Как работать с Cookie в HTTPClient?

Вопросы

Подскажите как сохранить ,а потом загрузить куки в THTTPClient , как понимаю нужно работать с TCookieManager

Сохранять пытаюсь так :

  cookies := aResponse.cookies.AsJSON(false);

В cookies получаю 

{\"Capacity\":4,\"Count\":3,\"List\":[{\"Name\":\"csrftoken\",\"Value\":\"Jljq2Sx5n9lXek4u4rri9L1zGBIExSzT\",\"Expires\":\"2019-01-06T18:41:36.854\",\"Domain\":\".i.instagram.com\",\"Path\":\"/\",\"Secure\":true,\"HttpOnly\":false},{\"Name\":\"rur\",\"Value\":\"PRN\",\"Expires\":\"1899-12-30T00:00:00.000\",\"Domain\":\".i.instagram.com\",\"Path\":\"/\",\"Secure\":false,\"HttpOnly\":false},{\"Name\":\"mid\",\"Value\":\"WlIjkQABAAF-JTqtAx_AdVdFxepj\",\"Expires\":\"2038-01-02T18:41:36.854\",\"Domain\":\".i.instagram.com\",\"Path\":\"/\",\"Secure\":false,\"HttpOnly\":false},{\"Name\":\"\",\"Value\":\"\",\"Expires\":\"1899-12-30T00:00:00.000\",\"Domain\":\"\",\"Path\":\"\",\"Secure\":false,\"HttpOnly\":false}],\"OnNotify\":null}

Но как потом загрузить это обратно?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 ответов на этот вопрос

  • 0

а почему Cookies.AsJson  ??

это же просто 

key=value;key=value;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Только что, krapotkin сказал:

а почему Cookies.AsJson  ??

это же просто 

key=value;key=value;

что бы удобнее было хранить 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Ну начал сохранять 

  for i := 0 to aResponse.cookies.Count - 1 do
  begin
    cookies := cookies + aResponse.cookies[i].ToString + ';';
  end;

как загрузить то их потом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Net.HttpClient.TCookieManager_Methods

тут только один метод что-то делает с куками, так что думаю, он и подойдет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 минуту назад, krapotkin сказал:

http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Net.HttpClient.TCookieManager_Methods

тут только один метод что-то делает с куками, так что думаю, он и подойдет

метод то один 

procedure TCookieManager.AddServerCookie(const ACookieData, ACookieURL: string);
var
  LURI: TURI;
  Values: TArray<string>;
  I: Integer;
begin
  if ACookieURL = '' then
    LURI := Default(TURI)
  else
    LURI := TURI.Create(ACookieURL);

  Values := ACookieData.Split([Char(',')], Char('"'));
  for I := 0 to High(Values) do
    AddServerCookie(TCookie.Create(Values[I], LURI), LURI);
end;

ACookieData - уже всех форматов попробовал ,не передает 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 часа назад, krapotkin сказал:

кстати

куки он передает, не заменяет только

проблему с загрузкой кук решил ,осталось понять почему не заменяет их 

 

 

Снимок.PNG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От gresaggr
      Всем привет.
      Работаю с DCEF3 последней ветки (https://github.com/hgourvest/dcef3).  Использую Delphi 10.1
      Нужно сделать две одновременно запущенных web версии whatsapp (https://web.whatsapp.com/)
      Динамически создаются два экземпляра Chromium с разными именами, user agent.
      Сначала создается первый и в нем появляется QR-код для авторизации через телефон. 
      После создания второго - в первом QR код исчезает и появляется ТОЛЬКО во втором. 
      Я так понимаю проблема в куках.
      Может кто знает как можно задать отдельную папку/хранить в память для каждого экземпляра?
       
      Сейчас задаю таким образом глобальный куки менеджер:
       CookiesPath := ExtractFilePath(Application.ExeName) + DEFAULT_COOKIES_DIR + currentNumber.ToString;  CM := TCefCookieManagerRef.Global(nil);  CM.SetStoragePath(CookiesPath, true, nil);  
      P.S.  Если запускать копию exe из той же папки где находятся все ресурсы хромиума, то такой проблемы нет.
      P.P.S. Еще заметил, что авторизованная сессия whatsapp не сохраняется после перезапуска программы. А тот же mail.ru сохраняется.
    • От kiz35196
      перевожу проект с инди на System.Net.HttpClient, никак не могу заставить его скачать файл,с инди всё как-то проще было
      подскажите пожалуйста
    • От Alex7wrt
      Добрый день
      В мобильном приложении используется следующая функция для чтения содержимого https страницы
      function geturlstring(url: string): string; var HTTP: THTTPClient; stream: tstringstream; begin try HTTP:=THTTPClient.Create; Stream:= TStringStream.Create('',TEncoding.UTF7); HTTP.Get(url, stream); Stream.Position:=0; Result:=stream.DataString; HTTP.Free; Stream.Free; except result:='error'; end; end; Почему-то в некоторых случаях, при подключении через WiFi, функция выдает 'error'. Хотя при проверке сам сайт с этим url открывается. Это вообще ссылка на гугловский сервис. Ошибку замечал например в WiFi сети метрополитена. Там подключение к WiFi двухэтапное - сначала открывается сервисная веб страница, нажимаешь ОК или что-то типа того, и WiFi подключается. 
      В этом случае функция выдает ошибку, хотя браузер работает, и другие и приложения типа мессенджера и вайбера видят сеть.В мобильных сетях вроде работает нормально, там ошибок не замечал.
      В чем может быть проблема? Может ли это быть потому, что url относится к https протоколу? 
       
    • От Rustam Bikeev
      Доброго времени суток уважаемые форумчане, назрел вопрос по компоненту ThttpClient. Я сам слеп в области Http что такое Post, Get  и прочие аббревиатуры для меня страшные и дикие звери которых никогда не видел. Потому и приходится спрашивать у вас. Как отправить на веб сервер запрос для получения текстового файла или картинки. Куда и как принять этот файл. Я нечерта не пойму если вы напишите сделай это сделай то, прошу вас опишите как пользоваться этими 3 функциями 
      THTTPClient.GetRequest
      THTTPClient.Post
      THTTPClient.Get
       
    • От notricky
      Собственно вопрос в том, что после авторизации клиент получает куку с хешем, который используется для подтверждения залогинености пользователя.
      В XE7 мне не удалось добавить полученную куку в новый запрос, отчего отправлять асинхронные запросы оказалось невозможным.
      В итоге вопрос: как добавить куки к новому запросу и нужен ли отдельный компонент клиента?
    • От Евгений Корепов
      Начал переносить проекты из XE8 в Berlin, столкнулся с странным затыком в простеньком коде - делаем запрос на сайт, получаем куки, делаем post авторизацию, получаем редирект, если все хорошо, то октрываем страницу из header Location. Выяснилось что не смотря на HTTPClient.AllowCookies:=True, в HTTPResponse.Cookies всегда пустота. Пришлось копать исходники. Вот что обнаружилось в source\rtl\net\System.Net.HttpClient.pas:
      procedure THTTPClient.ExecuteHTTPInternal(const ARequest: IHTTPRequest; const AContentStream: TStream; const AResponse: IHTTPResponse); var LRequest: THTTPRequest; LResponse: THTTPResponse; State: THTTPState; LExecResult: TExecutionResult; LClientCertificateList: TCertificateList; OrigSourceStreamPosition: Int64; OrigContentStreamPosition: Int64; OrigContentStreamSize: Int64; Status: Integer; LCookieHeader: string; begin LResponse := AResponse as THTTPResponse; LRequest := ARequest as THTTPRequest; OrigSourceStreamPosition := 0; if LRequest.FSourceStream <> nil then OrigSourceStreamPosition := LRequest.FSourceStream.Position; if AContentStream <> nil then begin OrigContentStreamPosition := AContentStream.Position; OrigContentStreamSize := AContentStream.Size; end else begin OrigContentStreamPosition := 0; OrigContentStreamSize := 0; end; State := Default(THTTPState); LClientCertificateList := TCertificateList.Create; try while True do begin LRequest.DoPrepare; // Add Cookies if FCookieManager <> nil then begin LCookieHeader := FCookieManager.CookieHeaders(LRequest.FURL); if LCookieHeader <> '' then LRequest.AddHeader('Cookie', LCookieHeader); // do not localize end; if not SetServerCredential(LRequest, LResponse, State) then Break; if not SetProxyCredential(LRequest, LResponse, State) then Break; if LRequest.FSourceStream <> nil then LRequest.FSourceStream.Position := OrigSourceStreamPosition; if LResponse <> nil then begin LResponse.FStream.Position := OrigContentStreamPosition; LResponse.FStream.Size := OrigContentStreamSize; end; LExecResult := DoExecuteRequest(LRequest, LResponse, AContentStream); case LExecResult of TExecutionResult.Success: begin if not SameText(LRequest.FMethodString, sHTTPMethodHead) then LResponse.DoReadData(LResponse.FStream); Status := LResponse.GetStatusCode; case Status of 200: begin Break; // Если запрос удачен, то выходим из цикла end; 401: begin State.Status := InternalState.ServerAuthRequired; end; 407: begin State.Status := InternalState.ProxyAuthRequired; end; else begin case Status of 301..304, 307: if FHandleRedirects and (LRequest.FMethodString <> sHTTPMethodHead) then begin Inc(State.Redirections); if State.Redirections > FMaxRedirects then raise ENetHTTPRequestException.CreateResFmt(@SNetHttpMaxRedirections, [FMaxRedirects]); end else Break; else end; State.Status := InternalState.Other; if DoProcessStatus(LRequest, LResponse) then Break; end; end; end; TExecutionResult.ServerCertificateInvalid: begin DoValidateServerCertificate(LRequest); end; TExecutionResult.ClientCertificateNeeded: begin DoNeedClientCertificate(LRequest, LClientCertificateList); end else raise ENetHTTPClientException.CreateRes(@SNetHttpClientUnknownError); end; if AllowCookies then UpdateCookiesFromResponse(LResponse); // Вот эта, критически важная процедура, при Status=200 никогда не выполняется end; // После выхода из цикла попадаем сюда if LRequest.FSourceStream <> nil then LRequest.FSourceStream.Seek(0, TSeekOrigin.soEnd); LResponse.FStream.Position := OrigContentStreamPosition; finally LClientCertificateList.Free; end; end; Т.е. разработчики исключили выполнение UpdateCookiesFromResponse(LResponse), которая помещает куки из ответа в HTTPClient.
      А вот код из XE8 который нормально работает с Cookies:
      function THTTPClient.ExecuteHTTPInternal(const ARequest: IHTTPRequest; const AContentStream: TStream): IHTTPResponse; var LRequest: THTTPRequest; LResponse: THTTPResponse; State: THTTPState; LExecResult: TExecutionResult; LClientCertificateList: TCertificateList; OrigSourceStreamPosition: Int64; OrigContentStreamPosition: Int64; OrigContentStreamSize: Int64; Status: Integer; LCookieHeader: string; begin Result := nil; LResponse := nil; LRequest := ARequest as THTTPRequest; OrigSourceStreamPosition := 0; if LRequest.FSourceStream <> nil then OrigSourceStreamPosition := LRequest.FSourceStream.Position; if AContentStream <> nil then begin OrigContentStreamPosition := AContentStream.Position; OrigContentStreamSize := AContentStream.Size; end else begin OrigContentStreamPosition := 0; OrigContentStreamSize := 0; end; State := Default(THTTPState); LClientCertificateList := TCertificateList.Create; try while True do begin LRequest.DoPrepare; // Add Cookies if FCookieManager <> nil then begin LCookieHeader := FCookieManager.CookieHeaders(LRequest.FURL); if LCookieHeader <> '' then LRequest.AddHeader('Cookie', LCookieHeader); // do not localize end; if not SetServerCredential(LRequest, LResponse, State) then Break; if not SetProxyCredential(LRequest, LResponse, State) then Break; if LRequest.FSourceStream <> nil then LRequest.FSourceStream.Position := OrigSourceStreamPosition; if LResponse <> nil then begin LResponse.FStream.Position := OrigContentStreamPosition; LResponse.FStream.Size := OrigContentStreamSize; end; LExecResult := DoExecuteRequest(LRequest, LResponse, AContentStream); case LExecResult of TExecutionResult.Success: begin if not SameText(LRequest.FMethodString, sHTTPMethodHead) then LResponse.DoReadData(LResponse.FStream); Status := LResponse.GetStatusCode; case Status of 200: begin Break; end; 401: begin State.Status := InternalState.ServerAuthRequired; end; 407: begin State.Status := InternalState.ProxyAuthRequired; end; else begin case Status of 301..304, 307: if FHandleRedirects and (LRequest.FMethodString <> sHTTPMethodHead) then begin Inc(State.Redirections); if State.Redirections > FMaxRedirects then raise ENetHTTPRequestException.CreateResFmt(@SNetHttpMaxRedirections, [FMaxRedirects]); end else Break; else end; State.Status := InternalState.Other; if DoProcessStatus(LRequest, LResponse) then Break; end; end; end; TExecutionResult.ServerCertificateInvalid: begin DoValidateServerCertificate(LRequest); end; TExecutionResult.ClientCertificateNeeded: begin DoNeedClientCertificate(LRequest, LClientCertificateList); end else raise ENetHTTPClientException.CreateRes(@SNetHttpClientUnknownError); end; end; if LRequest.FSourceStream <> nil then LRequest.FSourceStream.Seek(0, TSeekOrigin.soEnd); if AllowCookies then UpdateCookiesFromResponse(LResponse); // Здесь все верно, процедура за пределами цикла и выполняется всегда когда нужно. finally LClientCertificateList.Free; Result := IHTTPResponse(LResponse); end; end; А теперь вопрос: ну как так то? В продукте за 54 тысячи рублей сильно обидно исправлять такие косяки. Такое ощущение что разраб подрабатывал на стороне в проектах на php и забыл переключится на другой язык, там break прерывает работу аналога case и код работал бы правильно.
       
    • От netlink
      Добрый день!
      После переезда  с xe8 на Berlin 10.1
      получил проблему с тем, что в мобильном приложении перестали работать запросы.
       
      Сначала приходил coocie с Id сессии в которой мы работаем с сервером.
      И раньше в 8-ке при вызове всех дочерних запросов после аутентификации кука отправлялась на сервер и всё работало.
      Если в 10-ке открывать тот же проект без правок - то перестают работать все дочерние запросы.
      Смотрели откладку - на сервер куки перестали приходить?
      Это баг 10-ки или что-то делать надо ручками?
      Где про это написано?
      Спасибо!
      С уважением,
      Кондрашов Андрей
    • От Rusland
      Пытаюсь авторизоваться на локальном сервере:
      type TResponser = record Response: string; Code: integer; end; ... procedure TFrmLogin.OnAuthEvent(const Sender: TObject; AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName, APassword: string; var AbortAuth: Boolean; var Persistence: TAuthPersistenceType); var MyCredential: TCredentialsStorage.TCredential; begin MyCredential := TNetHTTPClient(Sender).CredentialsStorage.FindAccurateCredential(AnAuthTarget, ''); AUserName := MyCredential.UserName; APassword := MyCredential.Password; end; procedure TFrmLogin.OnValidateServerCertificate( const Sender: TObject; const ARequest: TURLRequest; const Certificate: TCertificate; var Accepted: Boolean); begin Accepted:=true; end; function TFormLogin.LoginToServer(login,pass:String):TResponser; var aResponse: IHTTPResponse; aResponser: TResponser; sStream: TStringStream; aHttpClient: TNetHTTPClient; begin try aHTTPClient := TNetHTTPClient.Create(nil); aHTTPClient.OnAuthEvent:=OnAuthEvent; aHTTPClient.OnValidateServerCertificate:=OnValidateServerCertificate; aHTTPClient.CredentialsStorage.AddCredential (TCredentialsStorage.TCredential.Create(TAuthTargetType.Server,'', sURL, login, pass)); aHTTPClient.AllowCookies :=true; aHTTPClient.AcceptLanguage:='ru-RU;q=0.8,en-US;q=0.5,en;q=0.3'; aHTTPClient.ContentType :='text/json'; aHTTPClient.AcceptCharset :='utf-8'; aHTTPClient.Accept :='text/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; try sStream := TStringStream.Create(); try aResponse := aHttpClient.Get(sURL, sStream); aResponser.Response:=sStream.DataString; aResponser.Code:=aResponse.StatusCode; // тут получаю код 200 Result:=aResponser; except end; finally sStream.Free; end; finally aHttpClient.Free; end; end;  
      После get cразу получаю код 200 (от ответного кода я решаю авторизован я или нет). Однако на сервер реально приходит 2 запроса: первый без basic authorization (и на него дается в ответ код 401), второй с basic authorization (на него уже в ответ код 200).
      Почему проходит два запроса, когда в программе я вижу только один? 
       
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу