Μετάβαση στο περιεχόμενο

Τεχνολογία · 7 Νοεμβρίου 2026 · 6 λεπτά ανάγνωσης

Webhooks απλά εξηγημένα: υπογραφή, επανάληψη, ασφάλεια

Τι είναι ένα webhook, πώς διαφέρει από το ερώτημα API και πώς χειρίζεστε υπογραφή, επανάληψη και διπλότυπα. Με curl και Node.

Δύο δρόμοι σε σύγκριση: στο ερώτημα API το σύστημά σας ρωτά ξανά και ξανά, στο webhook ο αποστολέας καλεί μία φορά τη διεύθυνσή σας μόλις συμβεί κάτι
Γράφημα: Whovisit · Προβολή του γραφήματος σε μεγάλο μέγεθος

Ένα webhook είναι ένα τηλεφώνημα προς την αντίθετη κατεύθυνση. Αντί το σύστημά σας να ρωτά κάθε λίγα λεπτά μια υπηρεσία αν συνέβη κάτι, η υπηρεσία καλεί μια διεύθυνση σε εσάς μόλις συμβεί. Αυτό εξοικονομεί ερωτήματα και παραδίδει νέα γρηγορότερα. Σε αντάλλαγμα πρέπει να διαθέσετε και να ασφαλίσετε έναν παραλήπτη. Το άρθρο εξηγεί και τα δύο.

Webhook ή ερώτημα API

Ερώτημα API (Polling)Webhook
Ποιος ξεκινά;Το σύστημά σαςΟ αποστολέας
Πότε;Με χρονοδιάγραμμα, π.χ. ανά ώραΜόλις συμβεί ένα συμβάν
ΠροσπάθειαΕρωτήματα ακόμη και χωρίς νέαΑπαιτείται προσβάσιμος παραλήπτης
Καλό γιαΑναφορές, συμφωνία, φόρτωση εκ των υστέρωνΕιδοποίηση, προώθηση
ΚίνδυνοςΚαθυστέρηση μέχρι το επόμενο ερώτημαΤο μήνυμα χάνεται, αν ο παραλήπτης δεν απαντά

Στην πράξη πολλοί συνδυάζουν και τα δύο: το webhook αναφέρει το συμβάν, το API φέρνει όταν χρειάζεται τις λεπτομέρειες ή κλείνει κενά μετά από μια διακοπή.

Πώς εξελίσσεται μια παράδοση

  1. Συμβαίνει ένα συμβάν, π.χ. «Εισήλθε πληρωμή».
  2. Ο αποστολέας στέλνει ένα POST με JSON στη διεύθυνση που έχετε δηλώσει (HTTPS).
  3. Ο παραλήπτης σας ελέγχει την υπογραφή, κρατά το μήνυμα και απαντά γρήγορα με έναν κωδικό από την περιοχή 2xx.
  4. Την πραγματική δουλειά την κάνει έπειτα το σύστημά σας.

Το βήμα 3 είναι σημαντικό. Η Stripe συστήνει στην τεκμηρίωση webhook να επιστρέφεται αμέσως κωδικός 2xx, πριν τρέξει σύνθετη λογική που θα μπορούσε να προκαλέσει timeout. Όποιος πρώτα καταχωρεί το τιμολόγιο και μετά απαντά, διακινδυνεύει περιττές επαναλήψεις.

Υπογραφή: πώς ελέγχετε την προέλευση

Η διεύθυνσή σας είναι δημόσια προσβάσιμη. Ο καθένας θα μπορούσε λοιπόν να στείλει σε αυτήν επινοημένα μηνύματα. Γι' αυτό οι αξιόπιστοι αποστολείς υπογράφουν κάθε μήνυμα με ένα κοινό μυστικό. Συνηθισμένο είναι ένα HMAC με SHA-256 πάνω στο περιεχόμενο, συχνά μαζί με χρονική σήμανση. Το GitHub περιγράφει τη διαδικασία ως εξής: HMAC-SHA256 πάνω στο περιεχόμενο, σε δεκαεξαδική μορφή, με την κεφαλίδα X-Hub-Signature-256. Η σύγκριση πρέπει να γίνεται με συνάρτηση σταθερού χρόνου εκτέλεσης, ώστε οι επιτιθέμενοι να μην συμπεραίνουν τίποτα από τους χρόνους απάντησης.

Σημαντικά σημεία για τον παραλήπτη σας:

  • Χρησιμοποιήστε το ακατέργαστο περιεχόμενο. Υπολογίστε την υπογραφή πάνω στα byte που λάβατε και όχι στο εκ νέου σειριοποιημένο JSON. Ήδη μια διαφορετική αλλαγή γραμμής αλλάζει την υπογραφή.
  • Ελέγξτε τη χρονική σήμανση. Η Stripe χρησιμοποιεί χρονική σήμανση στην υπογραφή και μια προεπιλεγμένη ανοχή πέντε λεπτών για να αποτρέπει επιθέσεις επανάληψης. Μια ανοχή 0 απενεργοποιεί τον έλεγχο.
  • Κρατήστε το μυστικό μυστικό. Όχι στον κώδικα, όχι στο repository, αλλά σε μια μεταβλητή περιβάλλοντος ή σε ένα θησαυροφυλάκιο.

Οδηγίες ανοιχτού κώδικα για αποστολείς και παραλήπτες συγκεντρώνει η πρωτοβουλία Standard Webhooks. Πώς σχηματίζει ο κάθε πάροχος συγκεκριμένα την υπογραφή του, αναγράφεται στην τεκμηρίωσή του.

Επαναλήψεις και διπλή παράδοση

Αν ο παραλήπτης σας δεν απαντά ή απαντά με κωδικό σφάλματος, ο αποστολέας προσπαθεί ξανά. Η Stripe π.χ. επαναλαμβάνει σύμφωνα με τη δική της τεκμηρίωση με αυξανόμενα διαστήματα έως και τρεις ημέρες. Άλλοι πάροχοι έχουν άλλους κανόνες, ορισμένοι απενεργοποιούν το webhook μετά από πολλές αποτυχίες. Από αυτό προκύπτει:

  • Υπολογίστε διπλότυπα. Το ίδιο συμβάν μπορεί να φτάσει πολλές φορές, ακόμη και όταν ο παραλήπτης σας λειτουργεί σωστά. Η Stripe το επισημαίνει ρητά.
  • Κάντε την επεξεργασία αδρανή ως προς την επανάληψη (idempotent). Δηλαδή: όποιος επεξεργάζεται το ίδιο μήνυμα δύο φορές, δεν παράγει δεύτερο αποτέλεσμα. Αποθηκεύστε το αναγνωριστικό του συμβάντος και προσπεράστε τα γνωστά.
  • Μην στηρίζεστε στη σειρά. Τα συμβάντα μπορεί να φτάσουν εναλλαγμένα. Ελέγξτε σε περίπτωση αμφιβολίας την τρέχουσα κατάσταση μέσω API.

Ασφάλεια και στις δύο πλευρές

Για παραλήπτες: μόνο HTTPS, έλεγχος υπογραφής και ηλικίας, περιορισμός του μεγέθους του μηνύματος, καμία εκτέλεση εντολών από το περιεχόμενο. Αντιμετωπίστε το περιεχόμενο όπως κάθε είσοδο από έξω.

Για αποστολείς που καλούν διευθύνσεις πελατών: όποιος προσφέρει webhooks, καλεί διευθύνσεις που έχουν καταχωρήσει άλλοι. Αυτός είναι ένας κλασικός δρόμος για Server-Side Request Forgery. Ο επιτιθέμενος καταχωρεί μια εσωτερική διεύθυνση. Ο διακομιστής την καλεί μέσα από το προστατευμένο δίκτυο. Η περιγραφή του OWASP αναφέρει ως στόχους π.χ. εσωτερικές υπηρεσίες και διευθύνσεις μεταδεδομένων παρόχων cloud. Λογικά μέτρα προστασίας:

  • να επιτρέπεται μόνο https://,
  • να επιλύεται η διεύθυνση κατά την καταχώρηση και πριν από κάθε κλήση και να απορρίπτονται ιδιωτικές, τοπικές και δεσμευμένες περιοχές,
  • να μην ακολουθούνται τυφλά οι προωθήσεις,
  • να τίθενται σύντομα χρονικά όρια.

Παράδειγμα: αποστολή δοκιμαστικού μηνύματος με curl

Με curl και openssl μπορείτε να δοκιμάσετε τον παραλήπτη σας χωρίς τον πραγματικό αποστολέα. Το σενάριο στέλνει ένα υπογεγραμμένο μήνυμα, όπως θα το έστελνε ένας αποστολέας με χρονική σήμανση:

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"

Παράδειγμα: ένας μικρός παραλήπτης σε Node.js

const http = require('http')
const crypto = require('crypto')
const GEHEIMNIS = process.env.WEBHOOK_GEHEIMNIS || 'test-geheimnis'
const gesehen = new Set() // στην πράξη: βάση δεδομένων

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)

Ο παραλήπτης ελέγχει υπογραφή και ηλικία, προσπερνά γνωστά αναγνωριστικά και απαντά αμέσως. Για τη λειτουργία χρειάζεστε επιπλέον HTTPS, περιορισμό μεγέθους και μια ουρά για την περαιτέρω επεξεργασία.

Πού είναι διαδεδομένα τα webhooks

Υπηρεσίες πληρωμών, πλατφόρμες κώδικα και εργαλεία φορμών αναφέρουν συμβάντα με webhook. Το κάνει και η αναγνώριση επισκεπτών: όταν το σύστημα αναφέρει μια εταιρεία που επισκέφθηκε τη σελίδα σας, καταλήγει απευθείας σε ένα εργαλείο της επιλογής σας. Πώς οδηγεί αυτό σε ένα σύστημα πωλήσεων, δείχνει το Φέρτε τις επισκέψεις ιστότοπου στο CRM. Την εναλλακτική μέσω ερωτήματος περιγράφει το Ποιες εταιρείες επισκέπτονται τον ιστότοπό μου;. Ποια δεδομένα ρέουν σε αυτό, εξηγεί το Πώς λειτουργεί η αναγνώριση εταιρειών;.

Συχνές ερωτήσεις

Ποια η διαφορά ανάμεσα σε webhook και API; Στο API το σύστημά σας ρωτά, στο webhook ο αποστολέας επικοινωνεί μόνος του. Και τα δύο μπορούν να συνδυαστούν.

Τι συμβαίνει αν ο παραλήπτης μου πάψει να λειτουργεί; Οι περισσότεροι αποστολείς επαναλαμβάνουν την παράδοση για ένα ορισμένο διάστημα. Πόσο και πόσες φορές, αναγράφεται στην τεκμηρίωση του παρόχου. Για κενά πρέπει να προγραμματίσετε μια συμφωνία μέσω API.

Αρκεί να ελέγχω τη διεύθυνση του αποστολέα; Όχι. Οι διευθύνσεις αποστολέα μπορούν να πλαστογραφηθούν και αλλάζουν. Αξιόπιστη είναι μόνο η υπογραφή με ένα μυστικό που γνωρίζετε μόνο εσείς και ο αποστολέας.

Διαβάστε περισσότερα