API auf Drupal 9 extern verfügbar machen

Hallo zusammen,

wir sind gerade dabei, unsere CiviCRM-Installation auf Drupal 9 und CiviCRM 5.45 zu upgraden.

Ich kämpfe nun schon ein paar Stunden damit, die API nach außen verfügbar zu machen. Scheinbar wurde die Authentifizierung komplett überarbeitet (siehe Doku) und auch die API-Endpunkte haben sich verändert, sodass extern/rest.php unter Drupal 9 nicht mehr zur Verfügung steht.

Ist es schon jemandem gelungen, die API unter Drupal 9 verfügbar zu machen?

Authentifizierung

Die Authentifizierung gelingt mir momentan nur mit einem JWT. Wenn ich meinem Request einen JWT im Header mitgebe, kann ich sehen, dass die Authentifizierung funktioniert hat:

$ curl --location --request GET 'https://example.com/civicrm/authx/id' \
> --header 'X-Civi-Auth: Bearer einsuperlangerjwt' 

{"contact_id":8,"user_id":null,"flow":"xheader","cred":"jwt"}

Mit einem API-Key im Header bekomme ich nur:

$ curl --location --request GET 'https://example.com/civicrm/authx/id' \
> --header 'X-Civi-Auth: Bearer eingueltigerapikey' 

HTTP 401 Login not permitted. Must satisfy guard (jwt, api_key).

Wenn ich auf dem Server mit einem cv ev 'Civi::settings()->set("authx_guards", ["api_key"]))' den Guard so setze, dass er nur den API-Key enthält, hilft das auch nicht:

$ curl --location --request GET 'https://example.com/civicrm/authx/id' \
> --header 'X-Civi-Auth: Bearer eingueltigerapikey'

HTTP 401 Login not permitted. Must satisfy guard (api_key).

So wie ich das verstanden habe, muss der Request auch nur einen der verlangten Guards erfüllen.

Auch das Anhängen des API-Keys als Parameter hilft leider nicht, gibt aber eine andere Fehlermeldung:

$ curl --location --request GET 'https://example.com/civicrm/authx/id?_authx=eingueltigerapikey' 

HTTP 401 Invalid credential

Nun ja, mit einem JWT sollte es ja vorerst funktionieren…

API-Endpunkte

Der Einzige Endpunkt, der mir momentan etwas sinnvolles ausspuckt ist:

https://example.com/civicrm/authx/id

Hier wird behauptet, dass der /ajax/rest Endpunkt den alten /extern/rest.php Endpunkt ersetzen soll.

https://example.com/civicrm/ajax/rest

Doch ein GET Request an https://example.com/civicrm/ajax/rest?entity=Group&action=get gibt mir nur die Login-Seite zurück. Das trifft sowohl mit einem JWT im Header und ohne jegliche Authentifizierung zu. Mit einer fehlerhaften Authentifizierung (korrekter API-Key oder manipulierter JWT) bekomme ich Fehlermeldungen.

Selbiges gilt auch für den im API-Explorer vorgeschlagenen Endpunkt:

https://example.com/libraries/civicrm/core/extern/rest.php

Unter dem Pfad lag zunächst gar keine rest.php. Das hier vorgeschlagene Anlegen eines symbolischen Links half auch nicht:

$ ln -s /var/www/example.com/vendor/civicrm/civicrm-core/extern /var/www/example.com/web/libraries/civicrm/core/

Ich habe eine Lösung gefunden.

Ersteinmal habe ich auf einen Tipp auf Mattermost hin auf CiviCRM 5.47.2 geupdatet.

Leider funktionierte es dann immer noch nicht sofort, was aber wohl an meinem Herumgefrickel mit dem neuen Authentifizierungssystem lag, in dem ich Guards definiert hatte. Nachdem ich diese wieder entfernt und der Legacy-API als erlaubte Authentifizierungsmethode den api_key hinzugefügt habe, wurden meine Requests dann endlich akzeptiert.

Der Vorteil an der Verwendung der Legacy-API ist wohl, dass sie noch immer den Site-Key (key) und den API-Key (api_key) als Querie-Parameter im Request akzeptiert und nur der Endpunkt auf https://example.com/civicrm/ajax/rest geändert werden muss. Allerdings frage ich mich, wie zukunftssicher das ist.

1 „Gefällt mir“