Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Zugriff auf Shopware REST API mit idHTTP (https://www.delphipraxis.net/171695-zugriff-auf-shopware-rest-api-mit-idhttp.html)

mocition 20. Nov 2012 14:32

Zugriff auf Shopware REST API mit idHTTP
 
Hallo,

ich würde gerne die REST API von Shopware (Link zur REST API Dokumentation) nutzen und versuche mit diesem Code darauf zugreifen:

Code:
var MemoryStream: TMemoryStream;
begin

  MemoryStream := TMemoryStream.Create;
  try
    IdHTTP1.Request.URL := 'http://localhost/api';

    IdHTTP1.Request.BasicAuthentication := true;
    IdHTTP1.Request.Username := 'meinApiUser';
    IdHTTP1.Request.Password := 'meinApiKey';

    IdHTTP1.get(IdHTTP1.Request.URL, MemoryStream);
    MemoryStream.Position:=0;
    Memo1.Lines.LoadFromStream(MemoryStream);
  finally
    MemoryStream.Free;
  end;
Leider bekomm ich da immer den Response: {"success":false,"message":"Invalid or missing auth"}

Wie muss ich den Request aufbauen, dass eine erfolgreiche Anmeldung funktioniert?

Danke.
mfg christoph

mjustin 20. Nov 2012 14:43

AW: Zugriff auf Shopware REST API mit idHTTP
 
Klappt es denn mit dem Browser (IE, Firefox)? Bei GET und Basic Auth kann man damit den Zugriff testen. Einfach die URL eingeben und dann User/Pass im Dialog eingeben.

Das wird auch in der Doku beschrieben:

Zitat:

Nachdem der API-Benutzer angelegt wurde sollten Sie zunächst testen, ob dieser korrekt konfiguriert wurde. Rufen Sie hierzu in Ihrem Browser den Frontend Controller "api" auf (http://www.ihredomain.de/api). Geben Sie in dem Authentifizierungsdialog als Benutzernamen den Shopware-Benutzernamen (1) und als Passwort den zugehörigen API-Key (2) ein.

http://wiki.shopware.de/Rest-API-Tut...r_Zugangsdaten

mocition 20. Nov 2012 14:52

AW: Zugriff auf Shopware REST API mit idHTTP
 
Hallo mjustin,

ja im Browser funktioniert es. Sowohl mit dem Anmelde-Dialog als auch mit http://meinApiUser:meinApiKey@localhost/api

mjustin 20. Nov 2012 14:59

AW: Zugriff auf Shopware REST API mit idHTTP
 
Ist es die aktuelle Indy Version (10.5.9)?

mocition 20. Nov 2012 15:07

AW: Zugriff auf Shopware REST API mit idHTTP
 
nein, es ist die Version 10.5.7.
Ich hol mir die aktuellste Version und probier es nochmals

mjustin 20. Nov 2012 15:20

AW: Zugriff auf Shopware REST API mit idHTTP
 
Das Beispiel

http://wiki.shopware.de/Rest-API-Tut...el_API_Clients

verwendet nicht Basic sondern Digest Authentifizierung.

Indy unterstützt Digest, aber dazu muss die Digest-Unit IdAuthenticationDigest eingebunden sein.

BasicAuthentication := true; muss weggelassen werden.

Genaueres kann man mit Fiddler als HTTP Proxy herausfinden, aber ich tippe es lag daran.

Weitere Tipps zum Debuggen sind hier: http://stackoverflow.com/questions/1...n-in-delphi-xe

mocition 20. Nov 2012 15:48

AW: Zugriff auf Shopware REST API mit idHTTP
 
Mit Digest Authetifizierung bekomm ich: HTTP/1.1 400 Bad Request

Code:
var MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  try
    IdHTTP1.Request.URL := 'http://localhost/api';

    IdHTTP1.Request.Authentication := TIdDigestAuthentication.Create;
    IdHTTP1.Request.Authentication.Username := 'meinApiUser';
    IdHTTP1.Request.Authentication.Password := 'meinApiKey';

    IdHTTP1.get(IdHTTP1.Request.URL, MemoryStream);
    MemoryStream.Position := 0;
    Memo1.Lines.LoadFromStream(MemoryStream);
  finally
    MemoryStream.Free;
  end;

mjustin 20. Nov 2012 16:03

AW: Zugriff auf Shopware REST API mit idHTTP
 
Zitat:

Zitat von mocition (Beitrag 1192092)
Mit Digest Authetifizierung bekomm ich: HTTP/1.1 400 Bad Request

Code:
var MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  try
    IdHTTP1.Request.URL := 'http://localhost/api';

    IdHTTP1.Request.Authentication := TIdDigestAuthentication.Create;
    IdHTTP1.Request.Authentication.Username := 'meinApiUser';
    IdHTTP1.Request.Authentication.Password := 'meinApiKey';

    IdHTTP1.get(IdHTTP1.Request.URL, MemoryStream);
    MemoryStream.Position := 0;
    Memo1.Lines.LoadFromStream(MemoryStream);
  finally
    MemoryStream.Free;
  end;

Ob Digest als Authentifizierungsmethode eingestellt ist, müsste man in der Konfiguration nachsehen.

Falls das nicht geht (wenn Shopware nicht auf einem eigenen Server installiert ist) ann man sich mit Fiddler die Methode ansehen.

Bei Digest wird der Server mit einem HTTP Header
WWW-Authenticate: Digest realm="testrealm@host.com",...

antworten und bei Basic halt mit
WWW-Authenticate: Basic ...


Die TIdDigestAuthentication.Create; Zuweisung macht Indy selber, der minimale Code wäre (ungetestet):

Code:
    IdHTTP1.Request.Authentication.Username := 'meinApiUser';
    IdHTTP1.Request.Authentication.Password := 'meinApiKey';

    Memo1.Lines.Text := IdHTTP1.get('http://localhost/api');

mocition 20. Nov 2012 18:40

AW: Zugriff auf Shopware REST API mit idHTTP
 
Digest Auth hab ich mal ausgelesen, verbinden kann ich aber immer noch nicht:
Code:
Digest username="meinApiUser",
realm="Shopware4 REST-API",
nonce="dc0e78ffcbef3a87b5e5bfd2719f38e6",
algorithm="MD5",
uri="/api/",
qop="auth",
nc=00000001,
cnonce="a387e108184985c695c70eb999bd4f9c",
response="4ba62efad9e4c33276e342b58128ddea",
opaque="d75db7b160fe72d1346d2bd1f67bfd10"

Union 20. Nov 2012 19:34

AW: Zugriff auf Shopware REST API mit idHTTP
 
Versuch es mal mit
Delphi-Quellcode:
IdHTTP1.Request.BasicAuthentication := False;

mocition 21. Nov 2012 10:27

AW: Zugriff auf Shopware REST API mit idHTTP
 
@Union:
BasicAuthentication auf False hat nicht geholfen.

Ich habe jetzt den Aufruf über den Browser gemacht und mit dem Fiddler mitgeloggt:
Code:
GET http://localhost/api HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Authorization: Digest username="meinApiUser", realm="Shopware4 REST-API", nonce="dae59ac3fd0442669a3afe9ab01d00ed", uri="/api", algorithm=MD5, response="7c44685e2cef635dc86a085b4f799e9d", opaque="d75db7b160fe72d1346d2bd1f67bfd10", qop=auth, nc=00000001, cnonce="082c875dcb2ca740"

mjustin 21. Nov 2012 10:58

AW: Zugriff auf Shopware REST API mit idHTTP
 
Zitat:

Zitat von mocition (Beitrag 1192191)
Ich habe jetzt den Aufruf über den Browser gemacht und mit dem Fiddler mitgeloggt:

Wie sieht der gleiche GET Request in Fiddler aus wenn das Delphi Programm ihn über Indy ausführt?

Firefox verwendet HTTP 1.1 und Keep-Alive, was bei Indy eventuell nicht Standard ist.

mocition 21. Nov 2012 12:32

AW: Zugriff auf Shopware REST API mit idHTTP
 
so schaut der Get Request mit dem Delphi Programm aus:
Code:
GET http://localhost/api HTTP/1.1
Connection: keep-alive
Host: localhost
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate,sdch, identity
Accept-Language: de-AT,de;q=0.8,en-US;q=0.6,en;q=0.4
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) RockMelt/0.16.91.483 Chrome/16.0.912.77 Safari/535.7
Warum sendet es da keine Digest Daten mit?

mjustin 21. Nov 2012 17:24

AW: Zugriff auf Shopware REST API mit idHTTP
 
Zitat:

Zitat von mocition (Beitrag 1192212)
so schaut der Get Request mit dem Delphi Programm aus:
Code:
GET http://localhost/api HTTP/1.1
Connection: keep-alive
Host: localhost
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate,sdch, identity
Accept-Language: de-AT,de;q=0.8,en-US;q=0.6,en;q=0.4
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) RockMelt/0.16.91.483 Chrome/16.0.912.77 Safari/535.7
Warum sendet es da keine Digest Daten mit?

Ganz normal - beim ersten GET ist dem Client nicht bekannt, wie er sich anmelden kann. Der Server sendet als Antwort einen 401 Error zurück um dem Client mitzuteilen, dass eine Authentifizierung benötigt wird, daraufhin wiederholt der Client den GET Request und gibt dann (also im zweiten Request auf die gleiche URL) die Anmeldedaten im Header mit.

Damit der Client weiss, wie man sich anmelden kann (also per Basic, Digest, NTLM oder anderen Verfahren) sendet der Server in seiner Antwort auf das erste GET auch einen Header in dem alle unterstützten Verfahren genannt werden.

(Da der Firefox Beispiel weiter oben auch schon die Digest Anmeldedaten enthält, kann es sich nicht um den ersten Request handeln, der hier mit Fiddler geloggt wurde).

Um das Problem zu analysieren braucht man die gesamte Kommunikation im Fiddler Protokoll, jeweils für Mozilla und Indy:

* erstes GET auf http://localhost/api
* die vollständige Response des Servers
* zweites GET http://localhost/api mit Digest Daten <- wenn Indy richtig konfiguriert ist, muss es hier auch den Digest Header mitsenden
* die vollständige Response des Servers

Erst im zweiten GET kann man erkennen, ob der Client die vom Server angeforderte Authentifizierungsmethode erkannt hat und benutzt.


:idea:Idee: die zweite Response - also nach erfolgreicher Anmeldung - könnte auch einen Redirect Header enthalten. Die IdHTTP HandleRedirects Property muss dann auf True gesetzt sein, damit der Client dem Redirect folgt:

http://stackoverflow.com/questions/4...page-redirects

mocition 21. Nov 2012 17:30

AW: Zugriff auf Shopware REST API mit idHTTP
 
Ich habe bei HTTPOptions die hoInProcessAuth aktiviert und jetzt werden die Digest Auth mitgeschickt:
Code:
GET http://localhost/api HTTP/1.1
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Host: localhost
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate,sdch, identity
Accept-Language: de-AT,de;q=0.8,en-US;q=0.6,en;q=0.4
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) RockMelt/0.16.91.483 Chrome/16.0.912.77 Safari/535.7
Authorization: Digest username="meinApiUser", realm="Shopware4 REST-API", nonce="7f4338ced0534cb49bc18082b6553bb3", algorithm="MD5", uri="http://localhost/api", qop="auth", nc=00000001, cnonce="5b6763567f8117e96f0247b701d3e4e3", response="d55a82a9d60bc3cbcc888eccd0a8288c", opaque="d75db7b160fe72d1346d2bd1f67bfd10"
Jetzt bekomme ich eine Exception "HTTP/1.1 404 Not Found".

Kann es sein, dass es an der uri in der Authorization liegt?
Wenn ja, wie kann ich die ändern auf "/api"?

mocition 21. Nov 2012 17:54

AW: Zugriff auf Shopware REST API mit idHTTP
 
ach ich Depp!!
Beim Zugriff über den Browser http://localhost/api meldet der Server auch eine "404 Not Found" zurück.
Wenn ich allerdings http://localhost/api/articles mit dem Server oder mit Delphi zugreife, dann bekomm ich "200 OK"

!!Danke für die Hilfe!!

hronny 30. Mär 2013 20:24

AW: Zugriff auf Shopware REST API mit idHTTP
 
Mich würde interessieren, ob du eine zweite Abfrage ausführen kannst. Bei mir funktioniert zwar der erste Aufruf wunderbar, beim zweiten Aufruf mit der gleichen Abfrage ergibt dann einen Fehler 400 Bad Request.
Eine Untersuchung mit Fiddler zeigte dann, dass nur bei der ersten Abfrage der Digest mitgesendet wird. Beim zweiten Aufruf steht nur "Digest" drin und nichts weiter.
Code:
procedure TForm1.Button2Click(Sender: TObject);
var s: String;
IdHTTP2: TIdHTTP;
begin
  try
    IdHTTP2 := TIdHTTP.Create();

    IdHTTP2.OnAuthorization := Auth;

    IdHTTP2.HTTPOptions := [hoInProcessAuth];
    IdHTTP2.Request.UserAgent := 'Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0';
    IdHTTP2.Request.Host := '192.168.1.1';
    IdHTTP2.Request.URL := 'http://192.168.1.1/shopware/api/orders/';
    IdHTTP2.Request.AcceptLanguage := 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';

    // Erster Aufruf
    s := IdHTTP2.get(IdHTTP2.Request.URL);
    Memo1.Lines.Add(s);

    // Zweiter Aufruf: Fehler 400
    s := IdHTTP2.get(IdHTTP2.Request.URL);
    Memo1.Lines.Add(s);
  finally
    IdHTTP2.Free;
  end;
end;
Die Auth-Routine sieht dann so aus:
Code:
procedure TForm1.Auth(Sender: TObject; Authentication: TIdAuthentication;
  var Handled: Boolean);
begin
  if not (sender is TIdHTTP) then exit;
  Authentication.Username:='admin';
  Authentication.Password:='apipasswort';
  if Authentication is TIdDigestAuthentication then begin
    with Authentication as TIdDigestAuthentication do begin
      Uri:=(Sender as TIdHTTP).Request.URL;
      Method:=(Sender as TIdHTTP).Request.Method;
    end;
  end;
  Handled:=True;
end;
Beim ersten Aufruf zeigt er im Fiddler die Authorizierung so an:
Code:
Authorization: Digest username="admin", realm="Shopware4 REST-API", nonce="174d221165c197bfb342ce5a4feb8504", algorithm="MD5", uri="http://192.168.1.1/shopware/api/orders/", qop="auth", nc=00000001, cnonce="2aff1b184c89e001e311096be805adae", response="73a424ad6d733aa915bb445850e7d448", opaque="d75db7b160fe72d1346d2bd1f67bfd10"
Beim zweiten Aufruf fehlt das alles
Code:
Authorization: Digest
Normal kann das so nicht richtig sein, da ein Browser sich auch nur einmal authorisieren muss.

geskill 30. Mär 2013 21:46

AW: Zugriff auf Shopware REST API mit idHTTP
 
Die kompletten HTTP vom Server wären interessant.

Mit
Delphi-Quellcode:
IdHTTP2.Request.URL
als URL zu arbeiten ist auch nicht ganz sinnvoll, während der Authentisierung wird dieser Wert überschrieben IdHTTP.DoRequest():
Delphi-Quellcode:
        wnAuthRequest:
          begin
            Request.URL := AURL;
          end;
Vielleicht hilft es schon
Delphi-Quellcode:
IdHTTP2.Request.Connection := 'Keep-Alive';
zu setzten.

Also du könntest es mal versuchen zwischen den beiden Requests
Delphi-Quellcode:
IdHTTP2.Request.Authentication.Next
aufrufen.

Innerhalb der
Delphi-Quellcode:
unit IdAuthenticationDigest
gibt es die Authentication Funktion. Die ist ganz interessant.

Intern wird über ein Zähler FCurrentStep der aktuelle Schritt gesetzt. Wenn du also deinen ersten Request absetzt, dann wird von der TIdHTTP Komponente über die TIdDigestAuthentication Komponente mittels der Funktion Authentication der Authentication Header erzeugt und FCurrentStep auf 0 gesetzt.

Beim nächsten Request ist dann FCurrentStep noch bei 0 und es wird als Authentication Header nur "Digest" zurückgegeben.

Am besten du gehst mit dem Debugger mal ganz langsam durch den Code.

EDIT:
Der nächste Request muss so aussehen, dass du [...] nc=00000002 [...] überträgst: http://en.wikipedia.org/wiki/Digest_...th_explanation ::
Zitat:

For subsequent requests, the hexadecimal request counter (nc) must be greater than the last value it used

hronny 31. Mär 2013 09:30

AW: Zugriff auf Shopware REST API mit idHTTP
 
Zitat:

Zitat von geskill (Beitrag 1209459)
Also du könntest es mal versuchen zwischen den beiden Requests
Delphi-Quellcode:
IdHTTP2.Request.Authentication.Next
aufrufen.

Genau das wars wohl! Danke Danke Danke! Geht nun so oft hintereinander wie ich will. Den Befehl Next konnte ich auf keiner Internetseite finden.

Ein
Delphi-Quellcode:
IdHTTP2.Request.Connection := 'Keep-Alive'
zu setzen hat nichts bewirkt, somit kann ich es ersteinmal weglassen. Gruß Ronny.

geskill 31. Mär 2013 11:09

AW: Zugriff auf Shopware REST API mit idHTTP
 
Eigentlich muss das Indy intern aufrufen, also sich selbstständig darum kümmern.

Ich werde das mal versuchen lokal zu reproduzieren und dann im Falle eines Fehlers (wovon ich ausgehe) melden.

hronny 31. Mär 2013 11:14

AW: Zugriff auf Shopware REST API mit idHTTP
 
Falls es hilft, ich arbeite mit Delphi 2007 und benutzte erst die enthaltenen Indys. Auf Grund der Fehler habe ich den Nightly Build geladen und diese ins Delphi integriert. Zwar haben die viele neue Funktionen und Parameter, aber der Fehler mit der Digest Authentifizierung war leider der gleiche.

geskill 31. Mär 2013 21:33

AW: Zugriff auf Shopware REST API mit idHTTP
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mit den aktuellen Indys klappt es.

Im März 2011 wurde die Digest Implementierung grundlegend überarbeitet.

Für die Installation, die nicht ganz so einfach ist, wenn man es das erste mal macht, gibt es ein Tutorial von einem Nutzer hier aus dem Forum ;) http://www.herrotto.de/delphiindy/

Ich empfehle den aktuellen Stand des trunks zu benutzen, da sich inzwischen unglaublich viel im Vergleich zu D2007 geändert hat!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz