Pereiti prie turinio

Technika · 2026 m. lapkričio 7 d. · 5 min. skaitymo

Webhook paprastai paaiškintas: parašas, pakartojimas, saugumas

Kas yra webhook, kuo jis skiriasi nuo API užklausos ir kaip tvarkyti parašą, pakartojimą bei dublikatus. Su curl ir Node pavyzdžiais.

Du keliai palyginimui: API užklausos atveju Jūsų sistema vis klausia, webhook atveju siuntėjas vieną kartą iškviečia Jūsų adresą, kai tik kas nors įvyksta
Grafika: Whovisit · Peržiūrėti grafiką dideliu dydžiu

Webhook yra skambutis priešinga kryptimi. Užuot Jūsų sistema kas kelias minutes klausinėjusi paslaugos, ar kas nors įvyko, paslauga iškviečia adresą pas Jus, kai tik tai įvyksta. Taip taupomos užklausos ir naujienos pateikiamos greičiau. Už tai turite parengti ir apsaugoti gavėją. Šis straipsnis paaiškina abu dalykus.

Webhook ar API užklausa

API užklausa (polling)Webhook
Kas pradeda?Jūsų sistemaSiuntėjas
Kada?Pagal tvarkaraštį, pavyzdžiui, kas valandąKai tik įvyksta įvykis
SąnaudosUžklausos ir be naujienųReikalingas pasiekiamas gavėjas
TinkaAtaskaitoms, suderinimui, papildomam įkėlimuiPranešimui, persiuntimui
RizikaVėlavimas iki kitos užklausosŽinutė pasimeta, jei gavėjas neatsako

Praktikoje daugelis derina abu: webhook praneša įvykį, API prireikus paima detales arba užpildo spragas po gedimo.

Kaip vyksta pristatymas

  1. Įvyksta įvykis, pavyzdžiui, „mokėjimas gautas“.
  2. Siuntėjas išsiunčia POST su JSON į Jūsų nurodytą adresą (HTTPS).
  3. Jūsų gavėjas patikrina parašą, įsimena žinutę ir greitai atsako 2xx srities kodu.
  4. Tikrąjį darbą Jūsų sistema atlieka vėliau.

3 žingsnis svarbus. Stripe webhook dokumentacijoje rekomenduoja nedelsiant grąžinti 2xx kodą, prieš vykdant sudėtingą logiką, kuri galėtų sukelti timeout. Kas pirmiausia užregistruoja sąskaitą, o tik paskui atsako, rizikuoja nereikalingais pakartojimais.

Parašas: kaip patikrinti kilmę

Jūsų adresas viešai pasiekiamas. Taigi bet kas galėtų siųsti jam išgalvotas žinutes. Todėl rimti siuntėjai pasirašo kiekvieną žinutę bendra paslaptimi. Įprastai tai HMAC su SHA-256 per turinį, dažnai kartu su laiko žyma. GitHub procedūrą aprašo taip: HMAC-SHA256 per turinį, pateikiamas šešioliktainiu pavidalu, su antrašte X-Hub-Signature-256. Palyginimas turi vykti funkcija su pastoviu vykdymo laiku, kad užpuolikai iš atsakymo laikų nieko neišvestų.

Svarbūs punktai Jūsų gavėjui:

  • Naudokite neapdorotą turinį. Parašą skaičiuokite iš gautų baitų, o ne iš iš naujo serializuoto JSON. Net kitoks eilutės lūžis pakeičia parašą.
  • Tikrinkite laiko žymą. Stripe parašuose naudoja laiko žymą ir numatytąjį penkių minučių toleranciją, kad užkirstų kelią pakartojimo atakoms. Tolerancija 0 išjungia patikrą.
  • Išlaikykite paslaptį paslaptyje. Ne kode, ne saugykloje, o aplinkos kintamajame ar saugykloje (seife).

Atvirojo kodo gaires siuntėjams ir gavėjams sujungia iniciatyva Standard Webhooks. Kaip kiekvienas tiekėjas konkrečiai sudaro savo parašą, aprašyta jo dokumentacijoje.

Pakartojimai ir dvigubas pristatymas

Jei Jūsų gavėjas neatsako arba atsako su klaidos kodu, siuntėjas bando dar kartą. Stripe, pavyzdžiui, pagal savo dokumentaciją kartoja didėjančiais intervalais iki trijų dienų. Kiti tiekėjai turi kitas taisykles, kai kurie išjungia webhook po per daug nesėkmių. Iš to išplaukia:

  • Tikėkitės dublikatų. Tas pats įvykis gali ateiti kelis kartus, net jei Jūsų gavėjas veikia teisingai. Stripe tai aiškiai pabrėžia.
  • Padarykite tvarkymą idempotentišką. Tai reiškia: kas tą pačią žinutę apdoroja du kartus, nesukuria antro rezultato. Išsaugokite įvykio identifikatorių ir praleiskite žinomus.
  • Nesiremkite eiliškumu. Įvykiai gali ateiti sumaišyti. Abejojant patikrinkite aktualią būseną per API.

Saugumas abiejose pusėse

Gavėjams: tik HTTPS, tikrinkite parašą ir amžių, apribokite žinutės dydį, nevykdykite komandų iš turinio. Su turiniu elkitės kaip su bet kuria įvestimi iš išorės.

Siuntėjams, kurie iškviečia klientų adresus: kas siūlo webhook, iškviečia adresus, kuriuos įrašė kiti. Tai klasikinis Server-Side Request Forgery kelias. Užpuolikas įrašo vidinį adresą. Serveris jį iškviečia iš apsaugoto tinklo. OWASP aprašas kaip taikinius nurodo, pavyzdžiui, vidines paslaugas ir debesų tiekėjų metaduomenų adresus. Prasmingos apsaugos priemonės:

  • leisti tik https://,
  • adresą išspręsti įrašant ir prieš kiekvieną iškvietimą bei atmesti privačias, vietines ir rezervuotas sritis,
  • nesekti nukreipimų aklai,
  • nustatyti trumpus laiko limitus.

Pavyzdys: bandomosios žinutės siuntimas su curl

Su curl ir openssl galite išbandyti savo gavėją be tikro siuntėjo. Scenarijus siunčia pasirašytą žinutę, kokią siųstų siuntėjas su laiko žyma:

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"

Pavyzdys: mažas gavėjas Node.js

const http = require('http')
const crypto = require('crypto')
const GEHEIMNIS = process.env.WEBHOOK_GEHEIMNIS || 'test-geheimnis'
const gesehen = new Set() // tikroje sistemoje: duomenų bazė

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)

Gavėjas patikrina parašą ir amžių, praleidžia žinomus identifikatorius ir atsako iš karto. Veikimui papildomai reikia HTTPS, dydžio apribojimo ir eilės tolesniam apdorojimui.

Kur webhook paplitę

Mokėjimo paslaugos, kodo platformos ir formų įrankiai įvykius praneša per webhook. Tai gali ir lankytojų atpažinimas: kai sistema praneša įmonę, kuri aplankė Jūsų puslapį, ji iškart patenka į Jūsų pasirinktą įrankį. Kaip tai veda į pardavimų sistemą, rodo Svetainės apsilankymų perkėlimas į CRM. Alternatyvą per užklausą aprašo Kokios įmonės lankosi mano svetainėje?. Kokie duomenys tuo metu teka, paaiškina Kaip veikia įmonių atpažinimas?.

Dažniausiai užduodami klausimai

Koks skirtumas tarp webhook ir API? API atveju Jūsų sistema klausia, webhook atveju siuntėjas pats pasiunčia žinią. Abu galima derinti.

Kas nutinka, jei mano gavėjas neveikia? Dauguma siuntėjų kartoja pristatymą tam tikrą laikotarpį. Kiek ilgai ir kaip dažnai, parašyta tiekėjo dokumentacijoje. Spragoms užpildyti suplanuokite suderinimą per API.

Ar pakanka patikrinti siuntėjo adresą? Ne. Siuntėjo adresus galima suklastoti, jie keičiasi. Patikimas tik parašas su paslaptimi, kurią žinote tik Jūs ir siuntėjas.

Skaityti toliau

Technika

IP geolokacija: kiek tiksli IP buvimo vieta?

Kaip atsiranda GeoIP duomenų bazės, kiek tikslios šalis, regionas ir miestas ir kodėl mobilusis ryšys, CGNAT ir VPN iškraipo statistiką bei šalių blokavimą.