Beantwortet

API (nicht REST) sagt "Wrong Hash"


Benutzerebene 4
Abzeichen +2

Ich versuche CSV-Exporte per API (ExportVorlageGet) abzurufen und richte mich nach dieser Anleitung:

https://community.xentral.com/hc/de/articles/360017436919-API-Dokumentation#h_01F1CJDD77Z6AVNRJ9QXD6AWDP

Der Code in Anleitung hat ja noch einen einen Fehler, api_id fehlt in der URL. Aber wenn ich das fixe, kommt beim Ausführen dieser Fehler:

SimpleXMLElement Object(    [status] => SimpleXMLElement Object        (            [action] => ExportVorlageGet            [message] => Wrong Hash            [messageCode] => 2        ))

In den Hash fließen zwei Parameter ein:

  1. appName oder remoteDomain (ist in der Doku auch nicht konsequent benannt). Hier verwende ich unsere Domain "https://xxxx.xentral.biz".
  2. initKey. Hier verwende ich den API key aus den Grundeinstellungen; API ist aktiviert.

Bei dem appName bin ich mir nicht ganz sicher, weil da das Handbuch auch nicht so weiterhilft ("$appName = 'NameDerApp';" - wie soll ich das interpretieren?). Aber weiter unten stand als Beispiel eben protokoll://domain ohne / am Ende.

Beim initKey / API key kann man eigentlich nichts falsch machen.

Was könnte der Grund für "Wrong Hash" sein?

Vielen Dank!

 

icon

Beste Antwort von Alexander Rabe 19 January 2022, 13:50

Original anzeigen

13 Antworten

Hallo Jakob,

sollte Dir hier niemand aus der Community helfen können, wende dich gern direkt per Ticket an unseren Support, dann schauen unserer Technik-Experte*innen gern mal drauf :) 

Beste Grüße,
Dennis Customer Success

Benutzerebene 4
Abzeichen +2

OK, mittlerweile habe ich per Ticket erfahren:

  • Die alte API gemäß der oben verlinkten Doku wurde von Xentral deaktiviert (oder so verändert, dass die Authentifizierung per Hash wie in der Doku beschrieben nicht mehr funktioniert). Sie soll nicht mehr verwendet werden (deprecated).
  • Stattdessen soll man die neue REST-API verwenden.
  • Der neuen REST-API fehlen aber noch viele Funktionen, die zur Zeit nur die alte API bietet.
  • Unter dem neuen REST-API endpoint soll es eine Möglichkeit geben, die alte API zu nutzen. Allerdings ist diese Option nicht ausreichend dokumentiert. “In diesem Fall erwartet die API immer einen POST-Request und die Nutzdaten müssen im Request-Body mitgeschickt werden.” Welche Nutzerdaten in welcher Form übergeben werden müssen steht weder in der alten Doku noch in der Doku der REST-API, und konnte ich auch nicht erraten oder dem Support nicht entlocken.
Benutzerebene 1

Hi Jakob, 

du kannst die Standard-API Endpoints (wie den von dir genannten) wie folgt nutzen. Die URL ist etwas seltsam, funktioniert dafür aber sowohl in der Cloud als auch auf selbstgehosteten Systemen.

URL:    https://deine_xentral_url.de/api/index.php?path=/ExportVorlageGet?id=1

Darauf mit GET zugreifen. Wichtig ist auch, dass der Bericht für die API freigegeben ist:

 

Payload kann leer sein. In die Headers muss außerdem  “Content-Type”: “application/xml” rein. Die Authentifikation ist per http digest. Hier gibst du dann den Api “App Name / Benutzername” als Username und den “Initkey / Passwort” als Passwort an.

Grüße

Lars (ruhr.agency) 

 

Benutzerebene 4
Abzeichen +2

Hi Lars,

danke für deine Antwort! Jetzt habe ich es genau so gemacht, wie du gesagt hast:

  • API-Account existiert mit username und password
  • Recht standard_exportvorlageget ist angehakt
  • Export-Vorlage mit ID 2 existiert (wie in deinem Screenshot)

Aufruf:

curl --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" \
-H 'Content-Type: application/xml' \
"https://schlievet.xentral.biz/api/index.php?path=/ExportVorlageGet&id=2"

Ergebnis:

EDIT: Funktioniert jetzt. Nach index.php kommt ein “?” und danach “&” Zeichen.

Anderer Aufruf:

curl --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" \
"https://schlievet.xentral.biz/api/v1/belege/auftraege/339?include=positionen"

In der verlinkten Dokumentation steht keine weitere Hilfe zu “Bad Request”. Haben wir vielleicht unterschiedliche Xentral Versionen (ich: 21.1)? Oder hast du dem API user noch zusätzliche Rechte geben müssen?

Was mich noch wundert, warum muss Content-Type xml sein? Die Antwort ist ja CSV und Content (Payload) gibt’s ja gar nicht, weil es ja nur ein GET ist…

Benutzerebene 1

Tatsache, ich hab einen Typo eingebaut. Das letzte ? in der URL ist falsch da muss ein “&” hin (weil das ? schon nach dem path-parameter steht). Also so:

 

https://deine_xentral_url.de/api/index.php?path=/ExportVorlageGet&id=1

 

Das müsste gehen. Sonst kannst du tatsächlich auch nochmal den Header weglassen, der ist hier ggf. unnötig (aber bei den Posts mit XML content wie zb. AuftragCreate schon).

Benutzerebene 4
Abzeichen +2

Oh, das hab ich auch übersehen. Ja mit dem “&” geht’s, danke!

Ohne dem Content-Type Header geht’s, allerdings kommt immer XML raus, also leider kein CSV, egal was für einen Accept Header man übergibt.

Leider auch noch ungültiges XML, das u.a. solche Zeilen enthält:

<
>
</
>

xmllint kann es nicht parsen. Aber mit einem awk oder sed script kann man es zur Not zu CSV umwandeln.

Danke!

Benutzerebene 1

Hey Jakob, dann noch ein Bonus Tipp an dieser Stelle. Schreib lieber einen SQL Bericht im Berichtemodul, geb den für die API frei und mach dann ein GET auf /v1/reports/{id}/download mit der JSON-API. Da kommt nämlich ein CSV raus und das funktioniert erfahrungsgemäß auch gut. Außerdem bist du nicht auf bestimmte Felder limitiert und kannst auch joins usw. machen.

Grüße

Benutzerebene 4
Abzeichen +2

Danke, das wäre eigentlich die bessere Lösung. Aber ich hatte da andere Probleme, z.B. konnte man aus irgendeinem Grund nicht nach dem Feld “useredittimestamp” sortieren. Fehler: “Reports can only use SELECT statements!” Nach anderen Feldern kann man aber sortieren... und ich wollte sortieren, damit ich nur die “recently edited” Adressen habe (mit LIMIT clause, die man aber auch nicht testen kann, weil dann wieder ein anderer Fehler kommt...).

Ansonsten hat mich bei den SQL Berichten noch die uralte MySQL Version gestört, die kein REGEX_REPLACE konnte (zum Vereinheitlichen von Telefonnummern) und, dass man die zu exportierenden Felder immer doppelt pflegen muss (im SQL-Eingabefeld und in der Tabelle darunter).

Aber CSV Export wär schonmal ein Bonus und dann muss ich halt post-processing machen...

Benutzerebene 4
Abzeichen +2

Fazit:

  • Die Standard-API kann wie oben von Lars beschrieben verwendet werden, ein Beispiel-Code dazu ist in meinem Beitrag darunter.
  • Die Authentifizierung per berechnetem Hash wie in der Xentral API Doku beschrieben, funktioniert nicht mehr. Stattdessen muss eben die HTTP Digest Authentifizierung verwendet werden.
Benutzerebene 3
Abzeichen +1

useredittimestamp und “Reports can only use SELECT statements!” habe ich hier auch. Und wieder keine Lösung...hach

Benutzerebene 4
Abzeichen +2

useredittimestamp und “Reports can only use SELECT statements!” habe ich hier auch. Und wieder keine Lösung...hach

Traurig auch, dass der Export von Berichten und Import/Export Zentrale verbuggt ist. Da dürfen deine Daten keine CSV-Trennzeichen und keine Anführungszeichen enthalten, was absurd ist für eine dedizierte Export-Funktion. Workaround ist ein REPLACE SQL-Befehl.

Aber ich hab grad in die Datenbank Ansicht geschaut, eventuell ist die Spalte “logdatei” sowas wie “useredittimestamp”? Danach könnte man dann sortieren. Kannst du mal testen.

select id, logdatei from adresse order by logdatei desc

 

Zur Fehlermeldung bei den Reports:

Das Report Modul von Xentral verbietet das Vorkommen folgender SQL Keywords im SQL Statement.

INTO, INSERT, UPDATE, DELETE, ALTER, SHOW, USE, TRUNCATE, LOAD, CREATE, DROP, RENAME

Damit soll sichergestellt werden, dass nur SELECT Abfragen erlaubt sind, und die DB nicht von Berichten geändert werden kann.
Bestehen Spaltennamen zufällig aus einen dieser Keywords, wie eben USEredittimestamp das verbotene Keyword USE, so ist die Query nicht erlaubt und es erscheint die Fehlermeldung
Reports can only use SELECT statements!.

Abhilfe schafft hier das Escapen der betroffenen Namen mit `` .

ORDER BY `useredittimestamp` funktioniert.
ORDER BY useredittimestamp funktioniert nicht.

Benutzerebene 4
Abzeichen +2

Zur Fehlermeldung bei den Reports:

Das Report Modul von Xentral verbietet das Vorkommen folgender SQL Keywords im SQL Statement.

Wow, danke. Darauf wäre ich nicht gekommen… komisch aber, dass es dann mit `useredittimestamp` geht. Wenn ich das programmiert hätte, hätte ich nach den verbotenen Wörtern mit word-boundary regex gesucht. Dann wäre useredittimestamp in Ordnung, egal ob mit oder ohne backticks.

 

Antworten