title | sidebarTitle | description |
---|---|---|
Verify webhooks from Nango |
Verify webhooks from Nango |
Step-by-step guide on how to verify the signatures of webhooks from Nango. |
Validate webhook provenance by looking at the X-Nango-Signature
header.
It's a SHA-256 hash generated using the secret key found in the Environment Settings in the Nango UI.
The webhook signature can be generated with the following code:
async (req, res) => {
const signature = req.headers['x-nango-signature'];
const isValid = nango.verifyWebhookSignature(signature, req.body);
}
import crypto from 'crypto';
const secretKeyDev = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
const signature = `${secretKeyDev}${JSON.stringify(payload)}`;
const hash = crypto.createHash('sha256').update(signature).digest('hex');
import hashlib
import json
secret_key_dev = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
signature = f"{secret_key_dev}{json.dumps(payload)}"
hash = hashlib.sha256(signature.encode('utf-8')).hexdigest()
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException {
String secretKeyDev = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
String payloadString = // convert payload to JSON string
String signature = secretKeyDev + payloadString;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(signature.getBytes("UTF-8"));
String hash = DatatypeConverter.printHexBinary(hashBytes).toLowerCase();
}
}
require 'json'
require 'digest'
secret_key_dev = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
signature = "#{secret_key_dev}#{payload.to_json}"
hash = Digest::SHA256.hexdigest(signature)
package main
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
)
func main() {
secretKeyDev := "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
payloadString, _ := json.Marshal(payload) // Handle error in real code
signature := secretKeyDev + string(payloadString)
hash := sha256.Sum256([]byte(signature))
hexHash := hex.EncodeToString(hash[:])
}
use sha2::{Sha256, Digest};
use serde_json::json; // Assuming use of serde_json for JSON serialization
let secret_key_dev = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
let signature = format!("{}{}", secret_key_dev, serde_json::to_string(&payload).unwrap());
let mut hasher = Sha256::new();
hasher.update(signature.as_bytes());
let hash = format!("{:x}", hasher.finalize());
<?php
$secretKeyDev = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$signature = $secretKeyDev . json_encode($payload);
$hash = hash('sha256', $signature);
?>
Only accept a webhook if the X-Nango-Signature
header value matches the webhook signature.