Tehnika · 2026. gada 7. novembris · 5 min lasīšanai
Webhooki vienkārši izskaidroti: paraksts, atkārtošana, drošība
Kas ir webhook, ar ko tas atšķiras no API vaicājuma un kā rīkoties ar parakstu, atkārtošanu un dublikātiem. Ar curl un Node piemēriem.
Webhook ir zvans pretējā virzienā. Tā vietā, lai Jūsu sistēma ik pēc dažām minūtēm pie pakalpojuma jautātu, vai kaut kas noticis, pakalpojums izsauc adresi pie Jums, tiklīdz tas notiek. Tas ietaupa vaicājumus un nodod jaunumus ātrāk. Pretī Jums jānodrošina un jāaizsargā saņēmējs. Šis raksts izskaidro abus.
Webhook vai API vaicājums
| API vaicājums (Polling) | Webhook | |
|---|---|---|
| Kas sāk? | Jūsu sistēma | Sūtītājs |
| Kad? | Pēc grafika, piemēram, ik stundu | Tiklīdz iestājas notikums |
| Piepūle | Vaicājumi arī bez jaunumiem | Vajadzīgs sasniedzams saņēmējs |
| Labi priekš | Pārskati, salīdzināšana, papildu ielāde | Paziņošana, tālāknosūtīšana |
| Risks | Aizkave līdz nākamajam vaicājumam | Ziņa pazūd, ja saņēmējs neatbild |
Praksē daudzi apvieno abus: webhook ziņo par notikumu, API pēc vajadzības paņem detaļas vai aizpilda robus pēc atteices.
Kā norit piegāde
- Iestājas notikums, piemēram, „maksājums saņemts“.
- Sūtītājs nosūta POST ar JSON uz Jūsu norādīto adresi (HTTPS).
- Jūsu saņēmējs pārbauda parakstu, atceras ziņu un ātri atbild ar kodu no 2xx diapazona.
- Faktisko darbu Jūsu sistēma veic pēc tam.
- solis ir svarīgs. Stripe webhook dokumentācijā iesaka nekavējoties atgriezt 2xx kodu, pirms tiek izpildīta darbietilpīga loģika, kas varētu izraisīt taimautu. Kas vispirms grāmato rēķinu un tad atbild, riskē ar nevajadzīgām atkārtošanām.
Paraksts: kā pārbaudīt izcelsmi
Jūsu adrese ir publiski sasniedzama. Tātad ikviens varētu tai sūtīt izdomātas ziņas. Tāpēc nopietni sūtītāji katru ziņu paraksta ar kopīgu noslēpumu. Parasti tas ir HMAC ar SHA-256 pār saturu, bieži kopā ar laika zīmogu. GitHub apraksta paņēmienu tā: HMAC-SHA256 pār saturu, attēlots heksadecimāli, ar galvenes rindu X-Hub-Signature-256. Salīdzināšanai jānotiek ar funkciju ar nemainīgu izpildes laiku, lai uzbrucēji no atbildes laikiem neko nevarētu secināt.
Svarīgi punkti Jūsu saņēmējam:
- Izmantot neapstrādāto saturu. Aprēķiniet parakstu pār saņemtajiem baitiem, nevis pār atkārtoti serializētu JSON. Jau cits rindas pārnesums maina parakstu.
- Pārbaudīt laika zīmogu. Stripe izmanto laika zīmogu parakstā un noklusējuma pielaidi piecas minūtes, lai novērstu atkārtošanas uzbrukumus. Pielaide 0 pārbaudi izslēdz.
- Noslēpumu turēt noslēpumā. Ne kodā, ne repozitorijā, bet vides mainīgajā vai seifā.
Atvērtā koda vadlīnijas sūtītājiem un saņēmējiem apkopo iniciatīva Standard Webhooks. Kā katrs sniedzējs konkrēti veido savu parakstu, rakstīts viņa dokumentācijā.
Atkārtošanas un dubultā piegāde
Ja Jūsu saņēmējs neatbild vai atbild ar kļūdas kodu, sūtītājs mēģina vēlreiz. Stripe, piemēram, pēc savas dokumentācijas atkārto ar pieaugošiem intervāliem līdz pat trim dienām. Citiem sniedzējiem ir citi noteikumi, daži webhook izslēdz pēc pārāk daudziem neveiksmīgiem mēģinājumiem. No tā izriet:
- Rēķinieties ar dublikātiem. Viens un tas pats notikums var ienākt vairākkārt, arī ja Jūsu saņēmējs strādā pareizi. Stripe uz to skaidri norāda.
- Padariet apstrādi idempotentu. Tas nozīmē: kas vienu un to pašu ziņu apstrādā divreiz, neveido otru rezultātu. Saglabājiet notikuma identifikatoru un izlaidiet zināmo.
- Nepaļaujieties uz secību. Notikumi var ienākt apmainīti. Šaubu gadījumā pārbaudiet aktuālo stāvokli ar API.
Drošība abās pusēs
Saņēmējiem: tikai HTTPS, pārbaudīt parakstu un vecumu, ierobežot ziņas izmēru, neizpildīt komandas no satura. Izturieties pret saturu kā pret jebkuru ievadi no ārpuses.
Sūtītājiem, kas izsauc klientu adreses: kas piedāvā webhooks, tas izsauc adreses, ko ierakstījuši citi. Tas ir klasisks ceļš uz Server-Side Request Forgery. Uzbrucējs ieraksta iekšēju adresi. Serveris to izsauc no aizsargātā tīkla. OWASP apraksts kā mērķus nosauc, piemēram, iekšējos pakalpojumus un mākoņsniedzēju metadatu adreses. Lietderīgi aizsardzības pasākumi:
- atļaut tikai
https://, - adresi ievadīšanas brīdī un pirms katra izsaukuma atrisināt un noraidīt privātus, lokālus un rezervētus diapazonus,
- nesekot pāradresācijām akli,
- iestatīt īsus laika ierobežojumus.
Piemērs: testa ziņas sūtīšana ar curl
Ar curl un openssl Jūs varat pārbaudīt savu saņēmēju bez īstā sūtītāja. Skripts sūta parakstītu ziņu, kādu sūtītājs sūtītu ar laika zīmogu:
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"
Piemērs: neliels saņēmējs Node.js
const http = require('http')
const crypto = require('crypto')
const GEHEIMNIS = process.env.WEBHOOK_GEHEIMNIS || 'test-geheimnis'
const gesehen = new Set() // īstenībā: datubāze
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)
Saņēmējs pārbauda parakstu un vecumu, izlaiž zināmos identifikatorus un atbild uzreiz. Darbināšanai Jums papildus vajadzīgs HTTPS, izmēra ierobežojums un rinda tālākai apstrādei.
Kur webhooki ir izplatīti
Maksājumu pakalpojumi, koda platformas un veidlapu rīki notikumus ziņo ar webhook. Arī apmeklētāju atpazīšana to var: ja sistēma ziņo par uzņēmumu, kas apmeklē Jūsu lapu, tas nonāk tieši Jūsu izvēlētā rīkā. Kā tas ved uz pārdošanas sistēmu, parāda Mājaslapas apmeklējumi CRM: 4 ceļi salīdzinājumā. Alternatīvu ar vaicājumu apraksta Kuri uzņēmumi apmeklē manu mājaslapu?. Kādi dati pie tā plūst, izskaidro Kā darbojas uzņēmumu atpazīšana?.
Biežāk uzdotie jautājumi
Kāda ir atšķirība starp webhook un API? API gadījumā Jūsu sistēma jautā, webhook gadījumā sūtītājs ziņo pats. Abus var apvienot.
Kas notiek, ja mans saņēmējs atslēdzas? Lielākā daļa sūtītāju piegādi atkārto noteiktu laika posmu. Cik ilgi un cik bieži, rakstīts sniedzēja dokumentācijā. Robiem Jums vajadzētu plānot salīdzināšanu ar API.
Vai pietiek pārbaudīt sūtītāja adresi? Nē. Sūtītāju adreses var viltot, un tās mainās. Uzticams ir tikai paraksts ar noslēpumu, ko zināt tikai Jūs un sūtītājs.