Problem z zalogowaniem sie do Prestashop przy uzyciu INDY

0

Witam,
chciałbym się zalogować do prestashop (https://www.portal_na_prestashpie_.pl/administrace/index.php?controller=AdminLogin) przy uzyciu IdHttp,
ale nie za bardzo moge zdiagnozować jakie dane idą metodą POST i jak je poustawiac w indy (dawno nie robilem takich cudow na kiju)

Czy ktoś moze logowal sie do presty juz i mi cos podpowie (może @kAzek )?

0

To podaj przykład takiego portalu (prawidłowych danych logowania raczej nie potrzebuje)

0

Otwórz "developer tools" w Chromie lub Firefox i podsłuchaj zapytanie.

4

Jak wiesz nie miałem poprawnych danych do zalogowania się ale na moje oko coś w tym stylu:

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  System.DateUtils, System.RegularExpressions, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.StdCtrls,
  IdZLibCompressorBase,IdCompressorZLib, IdIOHandler, IdIOHandlerSocket,
  IdIOHandlerStack, IdSSL,IdSSLOpenSSL, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    IdHTTP1: TIdHTTP;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    IdCompressorZLib1: TIdCompressorZLib;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    function GetUNIXTimeInMilliseconds: Int64;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetUNIXTimeInMilliseconds: Int64;
var
  DateTime: TDateTime;
  SystemTime: TSystemTime;
begin
  GetSystemTime(SystemTime);
  DateTime:= System.SysUtils.EncodeDate(SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay) +
        System.SysUtils.EncodeTime(SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
  result:= System.DateUtils.MilliSecondsBetween(DateTime, UnixDateDelta);
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  HOST = 'https://*********'; //domena bez / na końcu
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0';
  CONTENT_TYPE = 'application/x-www-form-urlencoded; charset=UTF-8';
  LOGIN_PAGE_URL_FRMT = '%0:s/administrace/ajax-tab.php?rand=%1:d';
  //%0:s - hasło
  //%1:s - email
  //%0:s - token
  LOGIN_POST_DATA_FRMT = 'ajax=1&controller=AdminLogin&submitLogin=1&passwd=%0:s&email=%1:s&redirect=&%2:s';
var
  sLoginURL: string;
  sHTML: string;
  sToken: string;
  sPostData: string;
  regex: TRegEx;
  match: TMatch;
  ss: TStringStream;
begin
  IdHTTP1.IOHandler:= IdSSLIOHandlerSocketOpenSSL1;
  IdHTTP1.Compressor:= IdCompressorZLib1;

  IdHTTP1.HandleRedirects:= True;
  IdHTTP1.Request.UserAgent:= USER_AGENT;
  IdHTTP1.Request.ContentType:= CONTENT_TYPE;

  sLoginURL:= Format(LOGIN_PAGE_URL_FRMT, [HOST, GetUNIXTimeInMilliseconds()]);
  sHTML:= IdHTTP1.Get(sLoginURL);

  regex:= TRegEx.Create('token=(.+?)"');
  match:= regex.Match(sHTML);
  if match.Success then  //udalo sie pobrac token
  begin
    sToken:= match.Value;
    sPostData:= Format(LOGIN_POST_DATA_FRMT, ['HASLO', 'ADRES@EMAIL', sToken]);

    ss:= TStringStream.Create(sPostData);
    ss.Position:= 0;

    sHTML:= IdHTTP1.Post(sLoginURL, ss);

    Memo1.Lines.Add(sHTML); //tu powinieneś mieć chyba JSON z info o powodzeniu lub nie logowania
  end;
end;

Oczywiście logowanie z użyciem SSL wiec pamiętaj o dodaniu wymaganych przez Indy bibliotek do folderu z programem.

0

Podpicowałem trochę, dodałem małe poprawki i działa sprawnie, dzięki.

Dla potomnych:

function GetUNIXTimeInMilliseconds: Int64;
var
  DateTime: TDateTime;
  SystemTime: TSystemTime;
begin
  GetSystemTime(SystemTime);
  DateTime := EncodeDate(SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay) + EncodeTime(SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
  Result := MilliSecondsBetween(DateTime, UnixDateDelta);
end;

function ExtractSecurityToken(const AValue: String): String;
var
  RegEx: TRegEx;
  Match: TMatch;
begin
  Result := '';

  if AValue <> '' then
  begin
    RegEx := TRegEx.Create('token=(.+?)"');
    Match := RegEx.Match(AValue);
    if Match.Success then
      Result := Copy(Match.Value, 1, Length(Match.Value) - 1);
  end;
end;

function TDcePacketeryWebAPI.GetOrderListInfo(): String;
const
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0';
  CONTENT_TYPE = 'application/x-www-form-urlencoded; charset=UTF-8';
  LOGIN_PAGE_URL_FRMT = '%0:s/administrace/ajax-tab.php?rand=%1:d';
  PACKETERY_PAGE_URL_FRMT = 'https://www.website.pl&%0:s';
  LOGIN_POST_DATA_FRMT = 'ajax=1&controller=AdminLogin&submitLogin=1&passwd=%0:s&email=%1:s&redirect=&%2:s';
var
  TargetURL: string;
  HTML: string;
  Token: string;
  PostData: string;
  StringStream: TStringStream;
begin
  Result := '';

  FHTTP.HandleRedirects := True;
  FHTTP.Request.UserAgent := USER_AGENT;
  FHTTP.Request.ContentType := CONTENT_TYPE;

  try
    TargetURL := Format(LOGIN_PAGE_URL_FRMT, [PRESTASHOP_DOMAIN, GetUNIXTimeInMilliseconds()]);
    HTML := FHTTP.Get(TargetURL);

    Token := ExtractSecurityToken(HTML);

    if Token <> '' then
    begin
      PostData := Format(LOGIN_POST_DATA_FRMT, [PRESTASHOP_ADMIN_PASSWORD, PRESTASHOP_ADMIN_EMAIL, Token]);

      StringStream := TStringStream.Create(PostData);
      try
        StringStream.Position := 0;
        HTML := FHTTP.Post(TargetURL, StringStream);
      finally
        StringStream.Free;
      end;

      Token := ExtractSecurityToken(HTML);
      TargetURL := Format(PACKETERY_PAGE_URL_FRMT, [Token]);

      Result := FHTTP.Get(TargetURL);
    end;
  except
    on E: Exception do
      raise Exception.CreateFmt('Wystąpił błąd podczas logowania do Prestashopa, szczegóły:%s%s', [#13#10, E.Message]);
  end;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1