PHP - Setup Webhook Receiver with signature verification
Asked Answered
O

1

5

I need to setup a PHP page for receiving Webhooks - I've done many of these in the past so that is not a problem, but the API I'm working with for this project requires that my webhook verifies the signature provided in the header.

As part of the validation request it will send the following:

HEADER:
 "x-xero-signature" : HASH_VALUE
PAYLOAD:
{
   "events": [],
   "lastEventSequence": 0,
   "firstEventSequence": 0,
   "entropy": "S0m3r4N0m3t3xt"
}

I've created a Webhook key (e.g. 'ABC123'), and as part of the validation request for this Webhook I must ensure that the payload which is hashed using HMACSHA256 with your webhook key and base64 encoded should match the signature in the header. This is a correctly signed payload. If the signature does not match the hashed payload it is an incorrectly signed payload.

To gain Intent to Receive validation, the receiving url must respond with status: 200 Ok for all correctly signed payloads and respond with status: 401 Unauthorized for all incorrectly signed payloads.

I'm a bit lost at this point as to how to go about this - the details for this setup can be found here:

https://developer.xero.com/documentation/getting-started/webhooks

Ossa answered 14/11, 2017 at 12:52 Comment(2)
What exactly are you having a problem with: Generating the corresponding hash or getting the value from the request header?Santanasantayana
@Santanasantayana both at this point - getting the value from the request header and then generating the corresponding hashOssa
S
7

To match the sent-in data with the validation hash in the header, you need to do the following things:

  1. Get the payload:
    $payload = file_get_contents("php://input");
  2. Generate a hash using the payload and your webhook key:
    $yourHash = base64_encode(hash_hmac('sha256', $payload, $yourWebhookKey));
  3. Check your hash against the one provided in the header:
    if ($yourHash === $_SERVER['x-xero-signature']) {}

You will have to check the $_SERVER array for the correct key if this does not work directly; it is probably all upper-case to begin with.

Edit: As noted by the OP, the correct variable is $_SERVER['HTTP_X_XERO_SIGNATURE']

Santanasantayana answered 14/11, 2017 at 13:8 Comment(4)
Thanks - that really helped me get through this. I had to use this format to get the header value $_SERVER['HTTP_X_XERO_SIGNATURE']Ossa
@Ossa That makes sense, I forgot about the HTTP_ part.Santanasantayana
I've updated the answer to match @user982124's comment.Comras
For anyone using this code and still having a "response not 200" issue, add the value "true" to the optional "Raw output" parameter of the hash_hmac function, which should get it working for you.Hollingshead

© 2022 - 2024 — McMap. All rights reserved.