Skip to content

Commit 34e14a9

Browse files
committed
docs: add webhook cryptographic verification guide
1 parent 75480ba commit 34e14a9

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

docs/WEBHOOKS.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# urBackend Webhooks Guide
2+
3+
Webhooks allow you to build event-driven applications by letting urBackend notify your custom external servers (like Next.js API routes, AWS Lambda, or Discord via Zapier) the absolute second data is added, updated, or removed from your database.
4+
5+
## Securing Your Webhooks (HMAC Verification)
6+
7+
Webhooks are sent as raw HTTP `POST` requests to a URL you configure. Because your webhook URL is public, anyone could theoretically send data to it.
8+
9+
To prove that the data came **only from urBackend**, every payload is signed using your project's unique "Signing Secret" (which you can generate or copy from the Webhooks Dashboard).
10+
11+
### How it Works
12+
13+
1. You create a Webhook in the urBackend Dashboard and either copy the auto-generated **Signing Secret** (e.g. `whsec_xyz123...`) or enter your own.
14+
2. When a data event occurs (like a new User signing up), urBackend packages the JSON data and computes an `HMAC-SHA256` signature using your secret.
15+
3. This signature is attached to the outgoing request in the `X-urBackend-Signature` header.
16+
4. Your server receives the request, performs the exact same HMAC math, and accepts the webhook only if the signatures match.
17+
18+
### Code Example (Node.js/Express)
19+
20+
Here is a copy-paste code snippet on how to safely verify an incoming urBackend webhook event.
21+
22+
```javascript
23+
const express = require('express');
24+
const crypto = require('crypto');
25+
const app = express();
26+
27+
// The secret provided by your urBackend Dashboard
28+
const URBACKEND_WEBHOOK_SECRET = process.env.URBACKEND_WEBHOOK_SECRET;
29+
30+
app.post('/urbackend-webhook', express.json(), (req, res) => {
31+
// 1. Extract the signature header sent by urBackend
32+
const signature = req.headers['x-urbackend-signature'];
33+
34+
// 2. Convert the raw request body payload to string
35+
const payload = JSON.stringify(req.body);
36+
37+
// 3. Compute the expected digest using HMAC-SHA256
38+
const expectedSignature = crypto
39+
.createHmac('sha256', URBACKEND_WEBHOOK_SECRET)
40+
.update(payload)
41+
.digest('hex');
42+
43+
// 4. Safely compare the signatures
44+
if (!signature || signature !== expectedSignature) {
45+
console.error("⚠️ Webhook verification failed! Potential spoofing attempt.");
46+
return res.status(401).send("Invalid signature");
47+
}
48+
49+
// 5. Success! The event is authentic.
50+
const { event, collection, payload: data } = req.body;
51+
52+
console.log(`✅ Received authentic ${event} event on ${collection}`);
53+
console.log("Record ID:", data._id);
54+
55+
// Always return a 200/20x as fast as possible to prevent timeouts
56+
res.status(200).send("Webhook received");
57+
});
58+
59+
app.listen(3000, () => console.log('Webhook server running on port 3000'));
60+
```
61+
62+
## Retry Logic
63+
64+
If your server takes too long to respond (timeout exceeding 10 seconds) or returns a `4xx / 5xx` HTTP status code, urBackend will mark the delivery as `failed`. The Webhook Dashboard provides a full "Delivery History" panel so you can inspect the exact payload, replay failed attempts, and debug your endpoint.

0 commit comments

Comments
 (0)