OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
MmVisual
Beiträge: 1470
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von MmVisual »

Hallo,

Heute habe ich eine sehr spezielle Frage. In den FPC Packages habe ich entsprechende Units gefunden, Beispiele aus dem Web haben bei mir irgendwie nicht so funktioniert wie ich mir das vorstelle.

Mein Ziel ist es über die Nexar API Bauteiledaten von elektronischen Bauteilen ab zu fragen, Bestelldaten von Lieferanten. Bei Nexar habe ich angefragt ob ich das in meine EXE implementieren darf und die haben zugestimmt. Nun bin ich dabei und habe zum (großen) Teil aus Unwissenheit das ein oder andere Problemchen, schlussendlich es geht nicht.

Wie das geht (ich verstanden habe)
1) Abfrage eines Tokens, der 24h dann gültig ist. Dazu muss man eine "ClientID" und ein "ClientSecret" an eine "TokenURL" URL senden und erhält dann den Token zurück.

2) Eigentliche Datenabfrage mit einer Query (JSON Format)

Mein Problem ist bei 1), also die Token Abfrage klappt nicht, daher geht natürlich 2) auch nicht. Aber erst mal eines lösen.

Am liebsten würde ich dazu "Synapse" verwenden, damit habe ich schon andere API Abfragen incl. SSL gelöst. Ich habe leider kein Beispiel gefunden wie man eine OAuth2 Abfrage mit Synapse macht und alles was ich probiert habe kam nur als Antwort dass die Anfrage ungültig ist. Von Synapse habe ich die aktuelle Sourcen von hier (https://github.com/geby/synapse) geladen und OpenSSL V3.2.1 geht schon mal damit (nach meinem Fix vor ein paar Tagen, der jetzt im GIT schon online ist).

Was ich jedoch gefunden habe sind in den FPC/source/packages/googleapi und habe dies ebenfalls probiert:

Code: Alles auswählen

uses .... googleclient, fpoauth2, fphttpwebclient;
  gOAuth2 := TGoogleClient.Create(Self);
  gOAuth2.AuthHandler := TOAuth2Handler.Create(Self);
  gOAuth2.WebClient := TFPHTTPWebClient.Create(Self);
  gOAuth2.Config.AuthMethod := amOAuth2;
  gOAuth2.Config.ApplicationName := 'EleLa';
  gOAuth2.AuthHandler.Config.ClientID := edClientID.Text;
  gOAuth2.AuthHandler.Config.ClientSecret := edClientSecret.Text;
  gOAuth2.AuthHandler.Config.TokenURL := 'https://identity.nexar.com/connect/token';
  gOAuth2.AuthHandler.Config.AuthURL := 'https://identity.nexar.com/connect/token';
  gOAuth2.AuthHandler.Config.AccessType := atOnline;
  gOAuth2.AuthHandler.Config.AuthScope := 'supply.domain';
  gOAuth2.AuthHandler.Authenticate; 
Mit der Funktion "Authenticate" sollte das dann eigentlich los gehen, da die Funktion jedoch "virtual" deklariert ist wird der Code nicht ausgeführt. Irgendwie stehe ich da komplett auf dem Schlauch was da noch fehlt.

(ClientID/ClientSecret darf ich hier nicht posten, das würde gegen deren Nutzungsbedingungen verstoßen)

Der Versuch mit Synapse:
Basierend auf das Demo von https://support.nexar.com/support/solut ... 1000471994 ganz unten.

Code: Alles auswählen

Var HTTP: THTTPSend;
  URLData: string;
  Result: Boolean;

  procedure WriteStrToStream2(const Stream: TStream; Value: AnsiString);
  {$IFDEF CIL}
  var
    buf: Array of Byte;
  {$ENDIF}
  begin
  {$IFDEF CIL}
    buf := BytesOf(Value);
    Stream.Write(buf,length(Value));
  {$ELSE}
    Stream.Write(PAnsiChar(Value)^, Length(Value));
  {$ENDIF}
  end;
  
  HTTP := THTTPSend.Create;
  HTTP.UserAgent:='Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0';

  URLData := '"grant_type": "client_credentials", "client_id": "' + edClientID.Text + '", ' +
    '"client_secret": "' + edClientSecret.Text + '", "scope": "supply.domain"';

  WriteStrToStream2(HTTP.Document, URLData);
  Result := HTTP.HTTPMethod('POST', 'https://identity.nexar.com/connect/token');

  if Result then
  Begin
    HTTP.Document.Position := 0;
    memAnswer.Lines.LoadFromStream(HTTP.Document);
  End;

  FreeAndNil(HTTP);
Den Text in URLData hatte ich auch mal in { } gesetzt (JSON Format), geht auch nicht.

Hier im Forum hatte ich einmal das gefunden:
viewtopic.php?f=26&t=14806

Darauf habe ich so wie in der Nexar Doku steht diesen Link zusammen gebaut:

Code: Alles auswählen

https://identity.nexar.com/connect/token?grant_type=client_credentials&client_id=<geheim>&client_secret=<geheim>&scope=supply.domain
Als Antwort erhalte ich:
{"error":"invalid_request"}
und nicht den Token.

Vielen Dank für die Hilfe.

VG Markus

PS: Sorry, ein Demo kann ich hier nicht wirklich posten, weil diese ID's ich nicht online stellen darf.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Stevie
Beiträge: 44
Registriert: Di 27. Feb 2024, 22:40

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von Stevie »

Moin Markus,

ich glaube, Du solltest Dich zunächst auf den OAuth2.0 Dialog selbst konzentrieren und die Lazarus-IDE beiseite lassen, bis der funktioniert. Nimm Dir einen API Client wie Bruno https://www.usebruno.com/ oder auch Curl und schau, dass Du die Anmeldung manuell hinbekommst. Wenn Du dann verstanden hast, wie die Rädchen ineinander greifen, lässt es sich viel einfacher ausprogrammieren.

Mit curl z.B.:

Code: Alles auswählen

curl -k -v -X POST -H "content-type: application/x-www-form-urlencoded" -d "grant_type=client_credentials&client_id=DEINE_ID&client_secret=DEIN_SECRET&scope=supply.domain" https://identity.nexar.com/connect/token
Da sollte dann u.a. ein Access Token rauskommen, das in allen nachfolgenden Anfragen als Bearer Token Header mitgeschickt werden muss: "Authorization: Bearer <ACCESS_TOKEN>".

Code: Alles auswählen

curl -k -v -X POST -H 'accept:application/json' -H 'connection:keep-alive'  -H "Authorization: Bearer ACCESS_TOKEN" -d '{ "query" : ... }' https://api.nexar.com/graphql
Wenn das funktioniert und somit sichergestellt ist, dass Client, Secret und der Umgang mit dem Access Token stimmen, kann man das mit Synapse oder dem fphttpclient in Code überführen...

MmVisual
Beiträge: 1470
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von MmVisual »

Vielen Dank für das CURL Demo :D

Teil 1, Abfrage des Tokens mit Synapse hat geklappt. Anhand der Verbose Ausgabe konnte ich Synapse genau gleich einstellen.

Teil 2, Abfrage der eigentlichen Daten bin ich noch dran. Es kommt nur ein "404" Fehler zurück. Die Query Syntax selbst funktioniert über die Nexar Webseite. Ich bin noch am suchen...

Der Query-Text, den man zu Nexar schickt sieht als Beispiel so aus:

Code: Alles auswählen

query pricingByVolumeLevels {
  supSearchMpn(q: "STM32H753VIT6", limit: 5) {
    hits
    results {
      part {
        mpn
        totalAvail
        sellers {
          company {
            name
          }
          offers {
            sku
            updated
            onOrderQuantity
            prices {
              quantity
              price
            }
          }
        }
      }
    }
  }
}
EleLa - Elektronik Lagerverwaltung - www.elela.de

Stevie
Beiträge: 44
Registriert: Di 27. Feb 2024, 22:40

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von Stevie »

Na, das ist doch schon mal ein guter Anfang!

Ein 404er steht ja für "(Page) Not Found", es mag also sein, dass das Part schlicht nicht gefunden wird. Es ist aber auch möglich, dass die Seite selbst nicht existiert. Ich würde auch jetzt wieder vorschlagen, die Abfrage zunächst mit curl oder Bruno zu testen und dann in Code zu gießen.

Code: Alles auswählen

curl -k -v -X POST -H 'accept:application/json' -H 'connection:keep-alive'  -H "Authorization: Bearer ACCESS_TOKEN" -d '{"query":"query q2 { supSearch(q: \"STM32H753VIT6\", limit: 5) { results { part { mpn manufacturer { name } } } } }"}' https://api.nexar.com/graphql
Eventuell sonst noch mal mit anderen Teilenummern versuchen.

MmVisual
Beiträge: 1470
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von MmVisual »

Vielen Dank für die Hilfe! :D

Ja, mit CURL hab ich das hin bekommen. Im großen und ganzen musste die "Query" noch als JSON verpackt werden.

Hier ein Lazarus Demo. Die EXE und DLL's habe ich mit im ZIP:
< ... im nächsten Beitrag mit Korrektur >

- Die ClientID / ClientSecret muss von Nexar.com beantragt werden
- Nach der einmaligen Eingabe wird die in einer INI Datei gespeichert.
- Der "Query" Text wird in der Datei "query.txt" gespeichert.
- Der AccessToken wird von Nexar geladen und ist 24h gültig
- Alle benötigten Dateien im ZIP, die EXE kann direkt ausgeführt werden. Erstellt mit Lazarus V3.0, Sourcen kann man unter Linux übersetzen und geht auch.
Zuletzt geändert von MmVisual am Fr 1. Mär 2024, 09:59, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Stevie
Beiträge: 44
Registriert: Di 27. Feb 2024, 22:40

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von Stevie »

Toll, dass es nun klappt und auch prima, dass Du ein Codebeispiel postest. Mir sind zwei Kleinigkeiten in dem Beispiel aufgefallen:

a) Du musst den 'User-Agent:' Prefix nicht angeben, wenn Du das Property HTTP.UserAgent setzt. Das macht die Library bereits. Ansonsten steht da nämlich ...

Code: Alles auswählen

User-Agent: user-agent: curl/7.81.0
b) Die Klasse TJsonData hat eine Helper-Methode namens FindPath (https://www.freepascal.org/docs-html/fc ... dpath.html), die dir das Iterieren über die Elemente erspart. Gerade bei komplexeren JSON-Strukturen wird der Code dadurch enorm viel lesbarer.

MmVisual
Beiträge: 1470
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: OAuth2 Tokenabfrage mit Synapse oder Googleclient?

Beitrag von MmVisual »

Thx für das drüber schauen.
Das eine war ein Copy/Paste Fehler, durch das viele hin und her testen.
FindPath ist nun drin.

Hier die Demo, incl Source:
Lazarus_Nexar_API_V4.zip
(3.72 MiB) 58-mal heruntergeladen
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten