diff --git a/content/webhooks-and-events/webhooks/securing-your-webhooks.md b/content/webhooks-and-events/webhooks/securing-your-webhooks.md index 4dfb86fdd76e..ebda07cb9686 100644 --- a/content/webhooks-and-events/webhooks/securing-your-webhooks.md +++ b/content/webhooks-and-events/webhooks/securing-your-webhooks.md @@ -112,6 +112,57 @@ def verify_signature(payload_body, secret_token, signature_header): raise HTTPException(status_code=403, detail="Request signatures didn't match!") ``` +### JavaScript example + +For example, you can define the following `verifySignature` function and call it in any JavaScript environment when you receive a webhook payload: + +```javascript +let encoder = new TextEncoder(); + +async function verifySignature(secret, header, payload) { + let parts = header.split("="); + let sigHex = parts[1]; + + let algorithm = { name: "HMAC", hash: { name: 'SHA-256' } }; + + let keyBytes = encoder.encode(secret); + let extractable = false; + let key = await crypto.subtle.importKey( + "raw", + keyBytes, + algorithm, + extractable, + [ "sign", "verify" ], + ); + + let sigBytes = hexToBytes(sigHex); + let dataBytes = encoder.encode(payload); + let equal = await crypto.subtle.verify( + algorithm.name, + key, + sigBytes, + dataBytes, + ); + + return equal; +} + +function hexToBytes(hex) { + let len = hex.length / 2; + let bytes = new Uint8Array(len); + + let index = 0; + for (let i = 0; i < hex.length; i += 2) { + let c = hex.slice(i, i + 2); + let b = parseInt(c, 16); + bytes[index] = b; + index += 1; + } + + return bytes; +} +``` + ### Typescript example For example, you can define the following `verify_signature` function and call it when you receive a webhook payload: