Allegro Rest Api - pierwsze kroki

0

Witam Was, webapi mam opanowane do perfekcji natomiast z REST nigdy nie miałem do czynienia ale po kolei. Wrzuciłem na formę 3 komponenty RestClient, RestRequest i RestResponse.
Z dokumentacji na allegro mniejwięcej tak wyglądać powinno zapytanie i to co powienienem otrzymać:

Przykładowy request do generowania kodu:

curl -X POST \
  'https://allegro.pl/auth/oauth/device' \
  -H 'Authorization: Basic base64(client_id:client_secret)' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'client_id={client_id}'

**
Przykładowy response:**

{
        user_code: "cbt3zdu4g",                             -- kod użytkownika - zalecamy 
                                                            przedstawić te dane użytkownikowi 
                                                            w postaci XXX XXX XXX. Taka forma 
                                                            będzie dla niego czytelniejsza 
                                                            przy przepisywaniu.
        device_code: "645629715",                           -- kod aplikacji - niezbędny 
                                                            do uzyskania tokenu dostępowego
        expires_in: "3600"                                  -- liczba sekund, przez które ważne są
                                                            oba kody
        interval: “5”,                                      -- wymagany odstęp (w sekundach) 
                                                            pomiędzy kolejnymi zapytaniami o 
                                                            status autoryzacji. Jeśli będziesz 
                                                            odpytywać częściej otrzymasz 
                                                            odpowiedź o statusie HTTP 400 z 
                                                            kodem: "slow_down".
verification_uri: “https://allegro.pl/skojarz-aplikacje”,   -- adres do weryfikacji użytkownika
verification_uri_complete: “https://allegro.pl/skojarz-aplikacje?code=645629715”   
                                                            -- adres do weryfikacji dla użytkownika z 
                                                            wypełnionym kodem użytkownika
}

Tutaj mój kod w delphi:

procedure Test;
begin
  RestClient.BaseURL := 'https://allegro.pl.allegrosandbox.pl';

  RestRequest.Method := TRESTRequestMethod.rmPOST;
  RestRequest.Resource := 'auth/oauth/device';
  RestRequest.AddParameter('Authorization','Basic '+EncodeBase64(client_id+':'+client_secret),TRESTRequestParameterKind.pkHTTPHEADER);
  RestRequest.AddParameter('Content-Type','application/x-www-form-urlencoded',TRESTRequestParameterKind.pkHTTPHEADER);
  RestRequest.AddParameter('client_id',client_id,TRESTRequestParameterKind.pkGETorPOST);
  RestRequest.Execute;

  Memo1.Text := RestResponse.Content;
end;

Aplikacja zarejestrowana na allegro i taka sama nazwa aplikacji ustawiona w delphi. W odpowiedzi w memo1 otrzymuję "nie można wyświetlić strony + cała strona główna allegro w htmlu"
Gdzieś robię błąd ale brak mi już pomysłów. Odpowiedź powinna być zupełnie inna.

0

słyszałem że WiRL jest bardzo dobry https://github.com/delphi-blocks/WiRL

0

Ale komponenty raczej nie są problemem gdyż jak zmienię jedną literę w

RestRequest.Resource := 'auth/oauth/device';

to otrzymuję w memo1 prawidłowy komunikat: **{"error":"unauthorized","error_description":"Full authentication is required to access this resource"} **

0

autoryzację masz robioną używając Base64, upewnij się że twoja funkcja base64 działa prawidłowo. Najlepiej zakoduj kawałek stringa tą funkcją i porównaj czy w wersji php (na jakiejś stronie) czy otrzymujesz ten sam wynik. Kiedyś miałem właśnie problem w podobnej sytuacji. Dodatkowo pisz kod używając UTF8 na wszelki wypadek.

0

To była pierwsza czynność jaką sprawdziłem :) Używam tej funckji z modułu: Synacode

curl -X POST \
  'https://allegro.pl/auth/oauth/device' \
  -H 'Authorization: Basic base64(client_id:client_secret)' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'client_id={client_id}'

Przyznam szczerze że za bardzo nie wiem co oznacza w powyższym zapisie -H oraz -d

0

-H to Header czyli nagłówek
i tu popełniasz bład
-d to Data czyli dane (parametry) które wysyłasz metodą POST

0

Napisałem taką procedurę w oparciu o Indy

procedure TForm2.Button1Click(Sender: TObject);
var
  Indy : TIdHTTP;
  IdSSL : TIdSSLIOHandlerSocketOpenSSL;
  Data : String;
  JSONToSend : TStringStream;
  Response: string;
begin
  Indy := TIdHTTP.Create(nil);
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Indy);
    IdSSL.SSLOptions.SSLVersions := [sslvTLSv1_2];
    Indy.IOHandler := IdSSL;
    Indy.Request.BasicAuthentication := False;
    Indy.Request.CustomHeaders.Values['Authorization'] := 'Basic '+EncodeBase64(client_id+':'+client_secret);
    Indy.Request.ContentType := 'application/x-www-form-urlencoded';
    Data := 'client_id='+client_id;
    JSONToSend := TStringStream.Create(Data,TEncoding.UTF8);
    try  
      Response := Indy.Post('https://allegro.pl.allegrosandbox.pl/auth/oauth/device',JSONToSend);
    finally
     JSONToSend.Free;
    end;    
     memo1.Text := Response;
  finally
    Indy.Free;
  end;
end;

I działa poprawnie zwraca to co potrzeba. Jednak jako że jestem uparty nadal nie potrafię sobie poradzić z kontrolkami Restclinet, restresponse. Teoretycznie nagłówek czyli header to jest to:


RestRequest.AddParameter('Authorization','Basic '+EncodeBase64(client_id+':'+client_secret),TRESTRequestParameterKind.pkHTTPHEADER);
RestRequest.AddParameter('Content-Type','application/x-www-form-urlencoded',TRESTRequestParameterKind.pkHTTPHEADER); 

natomiast dana to niby to

RestRequest.AddParameter('client_id',client_id,TRESTRequestParameterKind.pkGETorPOST);

Nawet próbuję wykorzystać Rest debugger od embarcadero i tam też nie mogę sobie poradzić. Gdzie się wprowadza nagłówki a gdzie dane?

0

Już sobie poradziłem z RestClient, RestResponse, RestRequest. popełniałem banalny błąd aż wstyd się przyznać. Jednakże zostanę chyba przy rozwiązaniu z Indy gdyż program będzie lżejszy.

0

Napisz, proszę, jaki to błąd, bo korzystając z Indy mam w odpowiedzi 401, a w przypadku RestClient - error connecting with SSL.

1

Co do błędów połączeń SSL zawsze sprawdzajcie aktualność bibliotek OpenSSL, bo w przypadku nieaktualnych serwery mogą po prostu odrzucać połączenie.

0

Zainstalowałem libeay32 i ssleay32.dll z 22-11-2018. Są jeszcze nowsze?

1

Tak, najnowszą wersją jest 1.0.2r. a na przyszłość to od tego jest numer wersji aby po tym rozpoznawać a nie szukać po dacie.
https://indy.fulgan.com/SSL/

0

Zainstalowałem tę, o której piszesz (openssl-1.0 .2r-i386-win32), jeszcze ciepła, z dzisiejszego ranka, ale dalej to samo. Próbowałem zarówno z typem aplikacji Web, jak i Device. Mam się wcześniej zalogować na stronie allegro lub allegrosandbox?

0

Nie widziałem Twojego kodu nawet w sumie nie bardzo rozumiem czy robisz na RestClient czy Indy ale zwróć uwagę na nagłówki. Jak chcesz pomocy to pokaż kod (to swoje ID sobie z x-ksuj) inaczej nikt nie wie w czym może być problem.

0

Załączam kod i odpowiedź zarejestrowaną przez idLogDebug

var
  Indy        : TIdHTTP;
  IdSSL       : TIdSSLIOHandlerSocketOpenSSL;
  JSONToSend  : TStringStream;
  postStrings : tstringlist;
  Response,
  l_data      : string;

begin
  Indy := TIdHTTP.Create(nil);
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Indy);
    IdSSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; //
    IdSSL.SSLOptions.Method      :=  sslvTLSv1_2;
    IdSSL.SSLOptions.Mode        :=  sslmUnassigned;
    Indy.HTTPOptions  := [hoForceEncodeParams];
    Indy.IOHandler    := IdSSL;
    idSSL.Intercept   := idLogDebug; 
    idLogDebug.Active := true;
    Indy.Request.BasicAuthentication := false;
    Indy.Request.CustomHeaders.Values['Authorization'] := 'Basic '+ EncodeBase64(client_id + ':' + client_secret);
    Indy.Request.ContentType := 'application/x-www-form-urlencoded';
    Indy.Request.AcceptLanguage := 'pl-PL';
    Indy.Request.UserAgent := 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Iron/35.0.1900.0 Chrome/35.0.1900.0 Safari/537.36';

    postStrings := TStringList.Create;
    postStrings.Encoding.UTF8;
    postStrings.Add('client_id=' + client_id);
    L_data := 'client_id=' + client_id;
    JSONToSend := TStringStream.Create(L_data,TEncoding.UTF8);

    try
      Response := Indy.Post('https://allegro.pl.allegrosandbox.pl/auth/oauth/device',JSONToSend);
      MemoContent.Text := Response;
      JSONToSend.Free;
    except
      on E: EIdHTTPProtocolException do
        ShowMessage('HTTP request failed'#13 + IntToStr(E.ErrorCode) + ' ' + E.Message);
      on E: EIdOpenSSLAPISSLError do
        ShowMessage('OpenSSL API failure'#13 + E.ClassName + #13'Result Code: ' + IntToStr(E.RetCode) + #13'Error Code: ' + IntToStr(E.ErrorCode));
      on E: EIdOpenSSLAPICryptoError do
        ShowMessage('OpenSSL crypto failure'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.ErrorCode));
      on E: EIdOpenSSLError do
        ShowMessage('Unknown OpenSSL error'#13 + E.ClassName + #13 + E.Message);
      on E: EIdSocketError do
        ShowMessage('Socket error'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.LastError) + ' ' + E.Message);
      on E: Exception do
        ShowMessage('Unexpected error'#13 + E.ClassName + #13 + E.Message);
    end;
  finally
    Indy.Free;
    JSONToSend.Free;
  end;
end;

Poniżej to co zarejestrował idLogDebug. To co niekoniecznie powinny oglądać osoby postronne jest w postaci {OPIS_POLA}

Debug Output:
Sent 2019-03-16 21:53:23: POST /auth/oauth/device HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Authorization: Basic {KOD_AUTORYZACJI}
Host: allegro.pl.allegrosandbox.pl
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
Accept-Language: pl-PL
User-Agent: User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Iron/35.0.1900.0 Chrome/35.0.1900.0 Safari/537.36

Process Allegro.exe (11492)
Debug Output: Sent 2019-03-16 21:53:23: client_id={CLIENT_ID} Process Allegro.exe (11492)
Debug Output:
Recv 2019-03-16 21:53:24: HTTP/1.1 401 Unauthorized
Date: Sat, 16 Mar 2019 20:53:25 GMT
Content-Type: text/html;charset=UTF-8
Connection: close
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
WWW-Authenticate: Basic realm="Allegro"
Content-Language: pl-PL
X-Backend: auth_{KOD_AUTH}
Vary: Accept-Encoding
Age: 0
X-Req-Counter: 1
Content-Security-Policy: block-all-mixed-content; report-uri https://allegroapi.io/seclog/csp;
X-Hit: HIT 0
X-Origin: plu-varnish-esi01
X-Content-Type-Options: nosniff
grace: none
X-XSS-Protection: 1; report=https://allegro.pl.allegrosandbox.pl/seclog/xss
X-Via-LB: hap-rnd-1b.dc4.local
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000
Set-Cookie: _cmuid={KOD_COOKIE}; Expires=Mon, 15 Mar 2021 20:53:26 GMT; Path=/; Domain=.allegro.pl.allegrosandbox.pl; Secure
0

Te zmienna postStrings mozna pominac, kombinowalem jeszcze z innym typem.

0

Strasznie ten kod sformatowany po wysłaniu, spróbuje jeszcze raz

procedure TForm1.Button3Click(Sender: TObject);

var   Indy        : TIdHTTP;
        IdSSL       : TIdSSLIOHandlerSocketOpenSSL;
        JSONToSend  : TStringStream;
        postStrings : tstringlist;
       Response,
       l_data      : string;

begin
  Indy := TIdHTTP.Create(nil);
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Indy);
    IdSSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; //
    IdSSL.SSLOptions.Method      :=  sslvTLSv1_2;
    IdSSL.SSLOptions.Mode        :=  sslmUnassigned;
    Indy.HTTPOptions  := [hoForceEncodeParams];
    Indy.IOHandler    := IdSSL;
    idSSL.Intercept   := idLogDebug; 
    idLogDebug.Active := true;
    Indy.Request.BasicAuthentication := false;
    Indy.Request.CustomHeaders.Values['Authorization'] := 'Basic '+ EncodeBase64(client_id + ':' + client_secret);
    Indy.Request.ContentType := 'application/x-www-form-urlencoded';
    Indy.Request.AcceptLanguage := 'pl-PL';
    Indy.Request.UserAgent := 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Iron/35.0.1900.0 Chrome/35.0.1900.0 Safari/537.36';
   
    L_data := 'client_id=' + client_id;
    JSONToSend := TStringStream.Create(L_data,TEncoding.UTF8);

    try
      Response := Indy.Post('https://allegro.pl.allegrosandbox.pl/auth/oauth/device',JSONToSend);
      MemoContent.Text := Response;
      JSONToSend.Free;
    except
      on E: EIdHTTPProtocolException do
        ShowMessage('HTTP request failed'#13 + IntToStr(E.ErrorCode) + ' ' + E.Message);
      on E: EIdOpenSSLAPISSLError do
        ShowMessage('OpenSSL API failure'#13 + E.ClassName + #13'Result Code: ' + IntToStr(E.RetCode) + #13'Error Code: ' + IntToStr(E.ErrorCode));
      on E: EIdOpenSSLAPICryptoError do
        ShowMessage('OpenSSL crypto failure'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.ErrorCode));
      on E: EIdOpenSSLError do
        ShowMessage('Unknown OpenSSL error'#13 + E.ClassName + #13 + E.Message);
      on E: EIdSocketError do
        ShowMessage('Socket error'#13 + E.ClassName + #13'Error Code: ' + IntToStr(E.LastError) + ' ' + E.Message);
      on E: Exception do
        ShowMessage('Unexpected error'#13 + E.ClassName + #13 + E.Message);
    end;
  finally
    Indy.Free;
    JSONToSend.Free;
  end;
end;
1

Ten kod działa (mimo że brzydki). Pytanie czy na pewno zarejestrowałeś swoją apkę na sandboxa a nie przypadkiem na normalnym allegro, skoro testujesz w środowisku sandbox? Bo tego co widzę w dokumentacji są osobne strony rejestracji. Zresztą zobacz tabelkę w części "Środowisko testowe" prawie na samym dole strony. https://developer.allegro.pl/about/#auth

0

Dzięki piękne, przy wejściu na stronę Sandbox i wybraniu Allegro API przekierowuje na stronę normalnego Allegro i tam się rejestruje apka.

0

Czy ktoś z Was może gdzieś jakiś tutorial widział i by wrzucił na forum co do REST API dla allegro, że by jakoś łatwiej było dla początkujących. Może macie jakieś źródła demo?

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