Signatur
Funktionsweise
Um die Herkunft des Webhooks und dessen Inhalt zu validieren, wird ein hash aus dem gesamten Webhook und einem nur dem Konsumenten und der CareSuite bekannten secret generiert.
Für jeden eingehenden Webhook muss dieser Hash überprüft werden. Nur wenn der errechnete Hash und der Hash im Webhook übereinstimmen, darf die Anfrage verarbeitet werden.
Für ein Beispiel siehe Webhooks → Quittierung → Beispiel für Verarbeitung.
Generierung
Folgende Werte des Webhooks werden zu einem String zusammengesetzt. Alle Werte sind durch einen . voneinander zu trennen.
| Wert | Beispiel |
|---|---|
| id | 8d8d52b6-ab21-4984-8abc-c5640b2e107e |
| target | 48:88:1F:C9:B0:BA |
| subject | element |
| event | updated |
| timestamp | 1460042371 |
| data (als JSON) | {"name":"Neuer Name"} |
{
"id": "8d8d52b6-ab21-4984-8abc-c5640b2e107e",
"target": "48:88:1F:C9:B0:BA",
"subject": "element",
"event": "updated",
"timestamp": "1460042371",
"respond_to": "/api/v1/webhooks/8d8d52b6-ab21-4984-8abc-c5640b2e107e",
"hash": "2c74049f7b3ce927cefaaa4162c98abe234f971f",
"data": {
"name": "Neuer Name"
}
}
Aus dem obenstehenden Webhook ergibt sich also folgender Prüfstring:
8d8d52b6-ab21-4984-8abc-c5640b2e107e.48:88:1F:C9:B0:BA.element.updated.1460042371.{"name":"Neuer Name"}
Aus diesem String wird nun ein Hash mit Schlüssel unter Verwendung von HMAC berechnet. Der verwendete Hash-Algorithmus ist sha256. Als Schlüssel wird das hinterlegte Hash-Secret verwendet.
Hinweis zum JSON-Format
Der JSON-String muss frei von nicht relevantem Whitespace sein. Es müssen also alle Zeilenumbrüche und Leerzeichen vor und nach den : entfernt werden.
Bei der Verwendung von JSON.NET unter C# können solche Strings mit Hilfe der Formatter.None Option generiert werden.
// http://stackoverflow.com/a/28456818
string json = jObject.ToString(Formatting.None);
Multibyte Unicode Zeichen sowie Slashes / dürfen nicht escaped werden. Die Strings sind UTF-8 codiert.
// Falsch (Leerzeichen / Slash und Umlaut escaped)
{"name" : "M\u00fcller\/Meier"}
// Richtig
{"name":"Müller/Meier"}
Beispielimplementierung in PHP
$hashString = implode('.', [
$webhook->id,
$webhook->target,
$webhook->subject,
$webhook->event,
$webhook->timestamp,
json_encode($webhook->data, JSON_UNESCAPED_UNICODE)
]);
// 8d8d52b6-ab21-4984-8abc-c5640b2e107e.48:88:1F:C9:B0:BA.element.updated.1460042371.{"name":"Neuer Name"}
$hash = hash_hmac('sha256', $hashString, 'secret');
// 08d70f4efd9dafcf5669cae4ff16f6c2ad9679460c9a85ef38d796abd646f68f
Beispielimplementierung in JavaScript
// https://github.com/brix/crypto-js
import * as CryptoJS from 'crypto-js';
const hashString = [
webhook.id,
webhook.target,
webhook.subject,
webhook.event,
webhook.timestamp,
JSON.stringify(webhook.data)
].join('.');
// 8d8d52b6-ab21-4984-8abc-c5640b2e107e.48:88:1F:C9:B0:BA.element.updated.1460042371.{"name":"Neuer Name"}
const hash = CryptoJS.HmacSHA256(hashString, 'secret').toString();
// 08d70f4efd9dafcf5669cae4ff16f6c2ad9679460c9a85ef38d796abd646f68f
Rückmeldung bei ungültigem Hash
Ist der Hash eines Webhooks ungültig, ist dessen Empfang mit einer HTTP-Response mit Status 400 Bad Request zu quittieren.
In diesem Fall darf der Webhook nicht weiterverarbeitet werden!
Für ein Beispiel siehe Webhooks → Quittierung → Beispiel für Verarbeitung.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"success": false,
"messages": [
{
"code": "invalid_hash",
"status_code": 400,
"errors": "Ungültiger Hash"
}
]
}