Technika · 2026. november 7. · 6 perc olvasási idő
Webhookok egyszerűen elmagyarázva: aláírás, ismétlés, biztonság
Mi az a webhook, miben különbözik az API-lekérdezéstől, és hogyan kezeli az aláírást, az ismétlést és a duplikátumokat. Curl és Node példával.
A webhook egy hívás a másik irányba. Ahelyett hogy az Ön rendszere néhány percenként rákérdezne egy szolgáltatásnál, történt-e valami, a szolgáltatás hív egy címet az Ön oldalán, amint megtörténik. Ez lekérdezéseket takarít meg, és gyorsabban hozza az újdonságokat. Cserébe Önnek egy fogadót kell biztosítania és védenie. Ez a cikk mindkettőt elmagyarázza.
Webhook vagy API-lekérdezés
| API-lekérdezés (polling) | Webhook | |
|---|---|---|
| Ki indítja? | Az Ön rendszere | A feladó |
| Mikor? | Ütemterv szerint, például óránként | Amint egy esemény bekövetkezik |
| Ráfordítás | Lekérdezések újdonság nélkül is | Elérhető fogadó szükséges |
| Mire jó | Jelentések, egyeztetés, utólagos betöltés | Értesítés, továbbítás |
| Kockázat | Késés a következő lekérdezésig | Az üzenet elvész, ha a fogadó nem válaszol |
A gyakorlatban sokan mindkettőt kombinálják: a webhook jelzi az eseményt, az API szükség esetén lekéri a részleteket, vagy kiegészíti a hiányosságokat egy kiesés után.
Hogyan zajlik egy kézbesítés
- Bekövetkezik egy esemény, például „fizetés beérkezett”.
- A feladó egy POST-ot küld JSON-nal az Ön által megadott címre (HTTPS).
- Az Ön fogadója ellenőrzi az aláírást, megjegyzi az üzenetet, és gyorsan válaszol egy 2xx tartományba eső kóddal.
- Az érdemi munkát utána az Ön rendszere végzi el.
A 3. lépés fontos. A Stripe a webhook-dokumentációban azt ajánlja, hogy azonnal adjon vissza egy 2xx kódot, mielőtt olyan költséges logika futna, amely időtúllépést válthat ki. Aki előbb könyveli a számlát, és csak utána válaszol, felesleges ismétléseket kockáztat.
Aláírás: hogyan ellenőrzi a származást
Az Ön címe nyilvánosan elérhető. Bárki küldhet tehát kitalált üzeneteket rá. Ezért a megbízható feladók minden üzenetet egy közös titokkal aláírnak. Szokásos egy HMAC SHA-256-tal a tartalom felett, gyakran időbélyeggel együtt. A GitHub így írja le az eljárást: HMAC-SHA256 a tartalom felett, hexadecimálisan megjelenítve, az X-Hub-Signature-256 fejléccel. Az összehasonlítást állandó futásidejű függvénnyel kell végezni, hogy a támadók ne tudjanak következtetni a válaszidőkből.
Fontos pontok a fogadójához:
- A nyers tartalmat használja. Az aláírást a kapott bájtok felett számítsa ki, nem az újra szerializált JSON felett. Már egy másik sortörés is megváltoztatja az aláírást.
- Ellenőrizze az időbélyeget. A Stripe időbélyeget használ az aláírásban és öt perces alapértelmezett tűrést az ismétléses támadások megakadályozására. A 0 tűrés kikapcsolja az ellenőrzést.
- A titkot tartsa titokban. Ne a kódban, ne a repositoryban, hanem egy környezeti változóban vagy egy széfben.
A feladókra és fogadókra vonatkozó nyílt forráskódú irányelveket a Standard Webhooks kezdeményezés gyűjti. Hogy minden szolgáltató konkrétan hogyan képezi az aláírását, az a dokumentációjában áll.
Ismétlések és kettős kézbesítés
Ha az Ön fogadója nem válaszol, vagy hibakóddal válaszol, a feladó újra próbálkozik. A Stripe például a saját dokumentációja szerint növekvő időközökkel ismétel, akár három napig. Más szolgáltatóknak más szabályaik vannak, egyesek túl sok sikertelenség után kikapcsolják a webhookot. Ebből következik:
- Számítson duplikátumokra. Ugyanaz az esemény többször is megérkezhet, még akkor is, ha az Ön fogadója helyesen dolgozik. A Stripe ezt kifejezetten jelzi.
- Tegye idempotenssé a feldolgozást. Ez azt jelenti: aki ugyanazt az üzenetet kétszer dolgozza fel, az nem hoz létre második eredményt. Tárolja az esemény azonosítóját, és hagyja ki az ismertet.
- Ne hagyatkozzon a sorrendre. Az események felcserélve is megérkezhetnek. Kétség esetén ellenőrizze az aktuális állapotot API-n át.
Biztonság mindkét oldalon
A fogadóknak: csak HTTPS, ellenőrizze az aláírást és a kort, korlátozza az üzenet méretét, ne hajtson végre parancsokat a tartalomból. A tartalmat kezelje úgy, mint bármely kívülről jövő bevitelt.
A feladóknak, akik ügyfelek címeit hívják: aki webhookokat kínál, olyan címeket hív, amelyeket mások jegyeztek be. Ez a Server-Side Request Forgery klasszikus útja. A támadó egy belső címet jegyez be. A szerver a védett hálózatból hívja meg. Az OWASP leírása célként például belső szolgáltatásokat és felhőszolgáltatók metaadat-címeit nevezi meg. Értelmes védelmi intézkedések:
- csak a
https://engedélyezése, - a cím feloldása a bejegyzéskor és minden hívás előtt, a privát, helyi és fenntartott tartományok elutasítása,
- az átirányítások vak követésének mellőzése,
- rövid időkorlátok beállítása.
Példa: tesztüzenet küldése curllel
A curllel és az openssl-lel tesztelheti a fogadóját a valódi feladó nélkül. A szkript egy aláírt üzenetet küld, ahogy azt egy feladó időbélyeggel küldené:
GEHEIMNIS="test-geheimnis"
ZEIT=$(date +%s)
INHALT='{"id":"evt_1","typ":"besuch.begonnen","firma":"beispiel-firma.example"}'
SIGNATUR="sha256=$(printf '%s.%s' "$ZEIT" "$INHALT" | openssl dgst -sha256 -hmac "$GEHEIMNIS" | sed 's/^.* //')"
curl -X POST http://localhost:3000/webhook \
-H "Content-Type: application/json" \
-H "X-Zeit: $ZEIT" \
-H "X-Signatur: $SIGNATUR" \
-d "$INHALT"
Példa: egy kis fogadó Node.js-ben
const http = require('http')
const crypto = require('crypto')
const GEHEIMNIS = process.env.WEBHOOK_GEHEIMNIS || 'test-geheimnis'
const gesehen = new Set() // élesben: adatbázis
http.createServer((req, res) => {
if (req.method !== 'POST' || req.url !== '/webhook') { res.writeHead(404); return res.end() }
const teile = []
req.on('data', t => teile.push(t))
req.on('end', () => {
const roh = Buffer.concat(teile).toString('utf8')
const zeit = req.headers['x-zeit'] || ''
const erwartet = 'sha256=' + crypto.createHmac('sha256', GEHEIMNIS).update(zeit + '.' + roh).digest('hex')
const erhalten = String(req.headers['x-signatur'] || '')
const a = Buffer.from(erwartet), b = Buffer.from(erhalten)
const echt = a.length === b.length && crypto.timingSafeEqual(a, b)
const frisch = Math.abs(Date.now() / 1000 - Number(zeit)) < 300
if (!echt || !frisch) { res.writeHead(401); return res.end() }
const ereignis = JSON.parse(roh)
if (!gesehen.has(ereignis.id)) { gesehen.add(ereignis.id); console.log('neu:', ereignis.typ) }
res.writeHead(200); res.end('ok')
})
}).listen(3000)
A fogadó ellenőrzi az aláírást és a kort, kihagyja az ismert azonosítókat, és azonnal válaszol. Az üzemeltetéshez ezenkívül HTTPS-re, méretkorlátra és a továbbfeldolgozás várakozási sorára van szüksége.
Hol terjedtek el a webhookok
A fizetési szolgáltatások, a kódplatformok és az űrlapeszközök webhookkal jelzik az eseményeket. A látogatóazonosítás is tudja: ha a rendszer jelez egy céget, amely az Ön oldalát látogatja, az közvetlenül egy Ön által választott eszközbe kerül. Hogy ez hogyan vezet egy értékesítési rendszerbe, azt a Weboldal-látogatások bevitele a CRM-be mutatja. A lekérdezéses alternatívát a Mely cégek látogatják a weboldalamat? írja le. Hogy milyen adatok áramlanak közben, azt a Hogyan működik a cégfelismerés? magyarázza.
Gyakori kérdések
Mi a különbség a webhook és az API között? Az API-nál az Ön rendszere kérdez rá, a webhooknál a feladó magától jelentkezik. Mindkettő kombinálható.
Mi történik, ha a fogadóm kiesik? A legtöbb feladó egy bizonyos időtartamon át ismétli a kézbesítést. Hogy meddig és milyen gyakran, az a szolgáltató dokumentációjában áll. A hiányokra tervezzen API-n át történő egyeztetést.
Elég ellenőrizni a feladó címét? Nem. A feladó címei megtéveszthetők és változnak. Megbízható csak az aláírás egy olyan titokkal, amelyet csak Ön és a feladó ismer.