API Authentifizierung - kann Token nicht finden
-
Hallo,
ich möchte mich über die CT-API anmelden. Dazu wollte ich vorgehen, wie hier beschrieben:
https://churchtools.academy/de/help/system-einstellungen/api/0-api-authentifizierung/Das Anmelden mit Benutzername und Passwort funktioniert auch, nur bekomme ich da kein Session-Cookie zurück.
Wenn ich dann gleich danach einen GET auf "logintoken" absetze bekomme ich einen 401.
Hier ein Beispiel mit curl:$ curl --header "Content-Type: application/json" --request POST --data '{"username":"...","password":"..."}' https://xxx-yyy.church.tools/api/login {"data":{"status":"success","message":"login.success","personId":1,"location":"?=churchhome"}}
Ok, hat erstmal funktioniert, nur kann ich da kein Session-Cookie entdecken.
Aber dann läuft der GET-Request schief:$ curl https://xxx-yyy.church.tools/api/persons/1/logintoken {"message":"Session expired!","translatedMessage":"Die Session ist abgelaufen, bitte logge dich erneut ein.","messageKey":"exception.unauthorized","args":[],"errors":[]}
Was mache ich falsch?
Liebe Grüße,
Gunther -
@GuntherZander, mehr als das musst du im Grunde nicht machen. Achte darauf, dass dein verwendeter Client die Session auch speichert. Mit Postman und Co. sollte das kein Problem sein. Was verwendest du?
-
@ohneworte Danke für die Antwort. Ich verwende einen JavaScript-Client. Der greift mittels fetch() auf die API zu:
fetch(`${this.#ctBaseUri}/login`, { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({username: username, password: password, rememberMe: false}) }) .then((response) => { return response.json(); }) .then((data) => { cb(data); }) .catch((error) => { console.error(`Error: ${error.message}`); });
Ich weiß nicht, wo ich in der Response das Session-Cookie herbekommen kann.
Im Callback cb(data) wird dann versucht das Token zu holen:fetch(`${this.#ctBaseUri}/persons/${personId}/logintoken`, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }).then(...)
Aber das läuft schief.
-
@GuntherZander Ich integriere selbst nicht mit JavaScript und kann dazu daher wenig/keinen Input geben. Meine Empfehlung ist aber die, dass du all deine Request-Chains (zb "Login - Token - User Information") in einem API-Client wie Postman vorab ausprobierst, um zu prüfen, ob in einem möglichst verlässlichen Umfeld schon mal alles funktioniert. Sobald du bereits "im Code" bist (z.B. JavaScript) können selbst Kleinigkeiten schnell zu Problemen führen.
-
@GuntherZander wenn du mit JS arbeitest würde ich dir unseren
@churchtools/churchtools-client
direkt als npm package empfehlen, der handhabt das alles direkt für dich -
@GuntherZander Ich habe eine Website mit javascript gemacht, bei der ich mich auch über die API anmelden kann. Das Cookie kommt beim login und wird vom Browser gespeichert. Es ist allerdings notwendig, dass du bei jedem neuen API-Request über fetch() auch das Cookie mitschickst. Bei dir fehlt da glaub ich noch die entsprechend Zeile nach den headers:
fetch(`${this.#ctBaseUri}/persons/${personId}/logintoken`, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, credentials: 'include', }).then(...)
Probiers mal damit.
-
@ohneworte Mit Postman funktioniert es. Da sehe ich auch den "set-cookie"-Header in der Login-Response. Dieser wird im Postman dann auch - irgendwie automatisch - dem logintoken-Request mitgegeben. Der gibt mir dann auch das Token zurück.
So weit so gut.
Jetzt hätte ich das auch gern in meiner Javascript-App. Wie kann ich das Session-Cookie dem aus dem login-Request dem logintoken-Request mitgeben?
Auslesen kann ich das ja leider nicht, das scheint für Cors-Requests gesperrt zu sein.
(siehe: https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) -
@DavidD Super! Danke. Das wars. Ich musste in beiden Requests also den login - und den logintoken-Request das credentials: 'include' mit reinnehmen.
Jetzt bekomme ich mein Token.Vielen Dank.