Validating the Webhook Signature
JavaScript / NodeJS Example
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/authenticate', async (req, res) => {
const hashSecret = "your_secret_here"; // Replace with your secret
const signatureHeaderKey = req.headers['quickbuy-signature'];
const rawBody = JSON.stringify(req.body); // Assuming JSON body
const rawSignature = rawBody + hashSecret;
const sha256 = crypto.createHash('sha256');
const keyToAccept = sha256.update(Buffer.from(rawSignature, 'utf8')).digest('base64');
if (keyToAccept === signatureHeaderKey) {
res.send("Authenticated");
} else {
res.status(401).send("Authentication failed");
}
});
Python Example
import hashlib
import base64
import json
async def authenticate():
hash_secret = "your_secret_here" # Replace with your secret
signature_header_key = request.headers.get('QuickBuy-Signature')
raw_body = json.dumps(request.json) # Assuming JSON body
raw_signature = (raw_body + hash_secret).encode()
sha256 = hashlib.sha256()
sha256.update(raw_signature)
key_to_accept = base64.b64encode(sha256.digest()).decode()
if key_to_accept == signature_header_key:
return "Authenticated"
else:
return "Authentication failed", 401
C# ASP.NET Example
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
public class Authentication
{
public async Task<bool> AuthenticateRequest(string hashSecret, HttpContext httpContext)
{
if (!httpContext.Request.Headers.TryGetValue("QuickBuy-Signature", out var headerKey))
{
return false;
}
using var ms = new MemoryStream();
await httpContext.Request.Body.CopyToAsync(ms);
var bodyBytes = ms.ToArray();
var rawSignature = bodyBytes.Concat(Encoding.UTF8.GetBytes(hashSecret)).ToArray();
using var sha256 = SHA256.Create();
var keyToAccept = Convert.ToBase64String(sha256.ComputeHash(rawSignature));
return keyToAccept == headerKey.FirstOrDefault();
}
}
Go Example
package main
import (
"crypto/sha256"
"encoding/base64"
"io"
"io/ioutil"
"net/http"
)
func authenticateRequest(w http.ResponseWriter, r *http.Request, hashSecret string) {
headerKey := r.Header.Get("QuickBuy-Signature")
if headerKey == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
defer r.Body.Close()
rawSignature := append(body, []byte(hashSecret)...)
hasher := sha256.New()
hasher.Write(rawSignature)
keyToAccept := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
if keyToAccept == headerKey {
w.Write([]byte("Authenticated"))
} else {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
}
}
func main() {
http.HandleFunc("/authenticate", func(w http.ResponseWriter, r *http.Request) {
authenticateRequest(w, r, "your_secret_here") // Replace with your secret
})
http.ListenAndServe(":3000", nil)
}
Last updated