Lompat ke konten utama

Contoh Praktis Web Hook: Panduan Implementasi yang Aman

Cari contoh web hook lengkap dengan code untuk Node.js, Python, dan Go. Pelajari cara memverifikasi tanda tangan dengan aman, mencegah serangan ulang, dan debug endpoint Anda.

Martin Donadieu

Martin Donadieu

Pengembang Konten

Contoh Praktis Web Hook: Panduan Implementasi yang Aman

You’ve got a service that needs to react when something happens somewhere else. A payment clears. A customer record changes. A repo gets a push. You could poll an API every minute and waste cycles asking “anything new?” over and over, or you can let the source system call you when the event happens.

Itu di mana artikel contoh web hook biasanya berhenti. Mereka menampilkan jalur, mencetak tubuh JSON, dan mengembalikan 200, dan panggil itu selesai. Versi itu berfungsi dengan baik hingga seseorang mengirimkan permintaan palsu, memulihkan yang valid, atau pengelola Anda rusak karena kerangka kerja memproses tubuh sebelum verifikasi tanda tangan.

Panduan ini mengambil jalur yang akan digunakan di produksi. Contoh-contoh yang kecil untuk dicopy, tetapi mereka termasuk bagian-bagian yang penting: penanganan tubuh mentah, verifikasi HMAC, pengecekan timestamp, pengakuan cepat, dan debugging yang praktis.

Daftar Isi

Apa itu Webhooks dan Mengapa Menggunakannya

Penyedia tagihan Anda menandai tagihan sebagai dibayar pada pukul 02:13. Jika aplikasi Anda belajar tentang hal itu pada pukul 02:14, pelanggan mendapatkan akses segera. Jika aplikasi Anda belajar tentang hal itu pada siklus polling berikutnya, mereka menunggu, dukungan mendapatkan tiket, dan log Anda penuh dengan kebisingan yang tidak perlu. Webhooks menyelesaikan masalah waktu dengan mengirimkan panggilan balik HTTP ketika event terjadi.

Dalam istilah praktis, sebuah webhook adalah POST berdasarkan event dari satu sistem ke sistem lain. Pemberi mendeteksi perubahan, seperti invoice.paid, order.created, atau push, dan mengirimkan data event ke URL yang Anda kendalikan. Itu menghilangkan loop

Mengapa pola ini muncul di sistem nyata karena itu dapat dihubungkan dengan peristiwa bisnis. Stripe mengirimkan hasil pembayaran. GitHub mengirimkan aktivitas repositori. Shopify mengirimkan pembaruan pesanan. Bentuknya sederhana, tapi perilaku produksi bukanlah. Webhook yang memperbarui uang, akses, atau persediaan harus mendapatkan perhatian yang sama seperti endpoint publik API apa pun, terutama setelah ulang coba, duplikat, dan lalu lintas tidak terpercaya masuk ke dalam gambar.

Model mental yang membantu

Cara yang berguna untuk menggambarkan aliran webhook adalah empat bagian yang bekerja bersama:

  • Sistem sumber. Layanan yang mendeteksi peristiwa.
  • Tujuan endpoint. Rute HTTP Anda yang menerimainya.
  • Peristiwa. Perubahan yang dinamai, seperti invoice.paid atau push.
  • Isi. Badan permintaan dengan detail yang dibutuhkan oleh code Anda.

Provider mengirim fakta tentang sesuatu yang sudah terjadi. Tugas Anda adalah untuk memverifikasi pengirim, memastikan permintaan masih segar, dan menerapkan perubahan sekali. Bagian terakhir itu lebih penting daripada banyak tutorial dasar yang mengakui.

Aturan praktis: Gunakan webhooks untuk pembaruan berdasarkan acara. Gunakan polling untuk bacaan yang dijadwalkan, backfills, atau penyedia yang tidak menawarkan acara keluar.

Untuk tim yang membangun lebih luas pemrosesan aliran kerja dan integrasi data, webhooks biasanya menjadi lapisan acara yang menjaga sistem tetap sinkron tanpa lalu lintas permintaan yang tidak perlu. Jika Anda bekerja pada layanan yang berat integrasi, artikel pengembangan backend Capgo bisa menjadi konteks yang berguna karena masalah inti muncul di sekitar retries, antrian, observabilitas, dan pengelolaan gagal. Apa yang berhasil dan apa yang gagal di produksi

Konfigurasi yang dapat bertahan baik biasanya membosankan oleh desain. Daftarkan diri hanya untuk acara yang Anda butuhkan. Tetapkan endpoint yang terbatas oleh penyedia atau keluarga acara. Simpan ID acara agar pengiriman duplikat tidak mengulangi efek sampingan. Kembalikan respons cepat 2xx sekali permintaan telah diverifikasi dan dijadwalkan, lalu lakukan logika bisnis yang lebih lambat secara asinkron.

For teams building broader workflow automation and data integration, webhooks usually become the event layer that keeps systems in sync without unnecessary request traffic. If you work on integration-heavy services, __CAPGO_KEEP_0__’s backend development articles are useful context because core problems show up around retries, queues, observability, and failure handling.

The versi yang rapuh mudah dikenali. Satu endpoint umum menangani segalanya. Pemeriksaan tanda tangan dilewati selama pengujian awal dan tidak pernah kembali. Penangan menulis langsung ke tabel kritis sebelum memeriksa apakah event tersebut autentik atau ketinggalan zaman. Hal ini berfungsi dalam demo dan gagal di bawah badai ulang, gangguan penyedia, atau penyerang merekam permintaan lama.

Perdagangan itu menentukan bagian lain dari panduan ini. Versi 'hello world' dari penerima webhook kecil. Versi yang siap produksi menambahkan verifikasi tanda tangan, pertahanan ulang, penanganan duplikat, dan hook debugging dari awal.

Anatomi Permintaan Webhook HTTP

Sebelum menulis code, membantu untuk melihat permintaan sebagai HTTP mentah daripada sebagai objek kerangka. Webhook biasanya hanya sebuah permintaan HTTP POST ke endpoint publik dengan header dan tubuh JSON.

Permintaan sederhana mentah

POST /webhooks/orders HTTP/1.1
Host: your-app.example
Content-Type: application/json
User-Agent: Provider-Webhooks/1.0
X-Webhook-Signature: sha256=abc123example
X-Webhook-Timestamp: 1712345678

{
  "event": "order.created",
  "id": "evt_123",
  "data": {
    "order_id": "ord_456",
    "status": "created"
  }
}

Bagian penting adalah sederhana:

  • Methode. Dalam prakteknya, pengiriman webhook biasanya adalah permintaan POST.
  • Content-Type. Sebagian besar penyedia modern mengirim JSON.
  • User-Agent. Bermanfaat untuk debugging, tetapi tidak cukup untuk kepercayaan.
  • Header Tanda Tangan. Mengandung verifikasi keaslian penyedia.
  • Header Waktu. Digunakan untuk menolak permintaan yang sudah kadaluarsa atau direplay.

Mengapa Bentuk Tubuh Berpengaruh

Objek Anda code biasanya tidak peduli dengan setiap field. Ia peduli dengan jenis event, identifikasi event, dan objek bisnis di dalamnya data. Oleh karena itu, pengelolaan yang baik hanya memproses apa yang dibutuhkan dan merekam yang lain untuk troubleshooting.

OpenAPI sekarang menggambarkan pola ini secara langsung. OpenAPI 3.1.0 menambahkan dukungan webhook kelas pertama dengan objek utama webhooks yang menggambarkan setiap webhook seperti Item Jalur tetapi diaktifkan oleh penyedia. Contoh yang paling umum menggunakan webhook dengan newPet operasi, tubuh permintaan JSON, dan post respons untuk menunjukkan bahwa pesan telah diterima, seperti yang ditunjukkan di bawah ini. 200 response untuk menunjukkan bahwa pesan telah diterima, seperti yang ditunjukkan di bawah ini. Contoh webhook OpenAPI.

Jika Anda sedang mendokumentasikan kontrak penerima atau penyedia sendiri, contoh yang kuat lebih berguna daripada prosa skema abstrak. Saya suka menggunakan referensi seperti Contoh dokumen SheetMergy’s API karena mereka membuat jelas bagaimana contoh permintaan, deskripsi bidang, dan respons yang diharapkan saling terkait.

Webhook sederhana pada lapisan transportasi. Banyak kegagalan datang dari kesalahpahaman tentang header, pengkodean tubuh, atau aturan tanda tangan.

Bagaimana Mengamankan Pembuktian Tanda Tangan Webhook

Webhook yang ditandatangani menjawab satu pertanyaan: apakah payload ini berasal dari seseorang yang tahu rahasia bersama?

Hal itu berbeda dari bertanya apakah permintaan itu baru atau apakah Anda sudah memprosesnya. Pembuktian tanda tangan adalah pintu gerbang pertama, bukan yang terakhir.

Infografis yang menggambarkan proses enam langkah untuk memverifikasi tanda tangan webhook untuk memastikan keaslian dan keamanan permintaan.

Alur Verifikasi

Alur HMAC biasa terlihat seperti ini:

  1. Baca tanda tangan dari header penyedia.
  2. Baca tubuh permintaan mentah Baca tubuh permintaan mentah secara tepat seperti yang diterima. Muat rahasia webhook Anda dari konfigurasi yang aman.
  3. Rekomputasi tanda tangan HMAC yang diharapkan menggunakan algoritma yang sama.
  4. Bandingkan tanda tangan yang diterima dan tanda tangan yang dihitung dengan perbandingan aman waktu.
  5. Tolak permintaan jika mereka tidak cocok.
  6. Langkah raw-body itu adalah tempat banyak implementasi yang baik lainnya gagal. Jika kerangka kerja Anda memparse JSON terlebih dahulu, mereformat spasi putih, atau mengubah detail pengkodean sebelum hashing, tanda tangan yang dihitung Anda tidak akan cocok dengan yang disediakan oleh penyedia.

Apa yang perlu diperhatikan dalam __CAPGO_KEEP_0__ yang nyata

What to watch for in real code

Menggunakan hash pada JSON yang diparsing

  • Jangan lakukanJangan melakukan JSON.stringify(req.body) And harapnya akan sesuai.
  • Menggunakan kesamaan string normal. Gunakan perbandingan aman waktu.
  • Menyimpan rahasia secara keras. Simpan mereka di variabel lingkungan atau manajer rahasia.
  • Mengandalkan header saja. Header tanda tangan hanya bermakna jika Anda memverifikasinya.

Untuk tim yang memperketat penanganan rahasia di antara layanan, panduan Capgo tentang keamanan API kunci untuk kinerja toko aplikasi relevant karena disiplin yang sama berlaku di sini. Rotasi rahasia, akses yang dipetakan, dan menghindari kebocoran di log semua penting untuk penerima webhook juga.

Contoh verifikasi umum

const crypto = require('crypto');

function verifySignature(rawBody, receivedSignature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  const a = Buffer.from(receivedSignature, 'utf8');
  const b = Buffer.from(expected, 'utf8');

  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

Ini sengaja umum. Pemasok nyata seringkali menambahkan tanda tangan, menggabungkan waktu menjadi konten yang ditandatangani, atau mengkodekan digest secara berbeda. Aturan tetap sama. Ikuti format tanda tangan yang tepat dari pemasok, dan selalu verifikasi terhadap payload mentah.

Melindungi Serangan Ulang

Webhook yang telah ditandatangani masih berbahaya jika sampai beberapa jam kemudian dan handler Anda menganggapnya sebagai yang baru. Hal itu lebih sering terjadi daripada tim yang diharapkan. Proksi merekam lalu lintas, isi permintaan payload bocor ke tempat yang salah, atau penyedia mengulangi setelah gagal jaringan dan endpoint Anda memproses event yang sama dua kali.

Daftar Periksa yang Menjelaskan Lima Langkah Utama untuk Mencegah Serangan Ulang dalam Aplikasi Web.

Verifikasi Tanda Tangan menjawab satu pertanyaan: apakah pengirim menciptakan payload ini dengan rahasia bersama? Perlindungan Ulang menjawab pertanyaan yang berbeda: apakah permintaan ini masih diterima sekarang juga? Penerima produksi membutuhkan kedua-duanya.

Periksaan Minimum yang Benar-Benar Penting

Pencegahan Ulang yang Praktis dimulai dengan timestamp yang ditandatangani. Penyedia mencantumkan timestamp di dalam header atau di dalam pesan yang ditandatangani, dan penerima Anda menolak permintaan yang jatuh di luar jendela toleransi yang kecil.

Alur yang harus terlihat seperti ini:

  • Baca timestamp dari lokasi yang ditentukan penyedia.Jangan menebak nama header.
  • Tampilkan sebagai bilangan bulat atau tanggal yang sesuai dengan format RFC,berdasarkan spesifikasi penyedia.
  • Bandingkan dengan jam server Anda.
  • Menolak permintaan yang terlalu tua atau terlalu jauh di masa depan.
  • Verifikasi tanggal sebagai bagian dari skema tanda tangan ketika penyedia mendukungnya.

Titik terakhir itu penting. Jika tanggal tidak tertutup oleh tanda tangan, seorang penyerang dapat mengganti tanggal segar dan memulai ulang tubuh asli. Saya selalu memeriksa format tanda tangan penyedia sebelum saya percaya logika tanggal.

Apa yang harus dipilih untuk jendela toleransi

Limah menit adalah default umum. Ini cukup pendek untuk mengurangi jendela serangan, tetapi cukup lama untuk bertahan melawan keterlambatan jam kecil dan keterlambatan jaringan normal.

Ada pertukaran di sini. Jendela 30 detik terdengar lebih aman, tetapi lebih sering gagal dalam sistem nyata, terutama ketika ulang coba, antrian, atau keterlambatan regional terlibat. Jendela 30 menit lebih mudah dioperasikan, tetapi memberikan penyerang waktu yang lebih lama jika permintaan yang ditandatangani terbuka.

Pertahanan ulang bukan hanya verifikasi tanggal

Validasi tanggal menghalangi permintaan yang ketinggalan. Ini tidak menghentikan pengolahan duplikat di dalam jendela yang valid. Jika event yang ditandatangani yang sama disampaikan dua kali dalam jendela itu, aplikasi Anda masih perlu mengenali itu.

Gunakan lapisan kedua:

  • Track ID event atau ID pengiriman di penyimpanan yang hidup singkat seperti Redis.
  • Tangani handler sebagai idempoten sehingga pengiriman yang diulang tidak menciptakan pesanan duplikat, email, atau aksi tagihan.
  • Tulis permintaan yang ditolak yang sudah kadaluarsa dengan kode alasan, tetapi tidak pernah tulis rahasia atau muatan sensitif penuh.
  • Kembalikan respons yang cepat setelah validasi dan pekerjaan antrian berat di tempat lain.

Tim yang sudah berpikir tentang jendela kedaluwarsa dan revokasi akan mengenali pola ini. Panduan Capgo ke pola revokasi token di aplikasi Capacitor menutupi ide operasional yang sama. Kredensial atau permintaan yang valid sekali tidak boleh dipercaya selamanya.

Tanda tangan dan kadaluarsa masih berbahaya.

Membangun Penerima Webhook di Node.js

Node dengan Express masih cara yang paling cepat untuk mendapatkan penerima serius online, tetapi ada satu perangkap yang lebih penting dari perangkap lainnya. Anda memerlukan akses ke tubuh mentah sebelum Express mengubahnya menjadi objek.

Sebuah laptop di atas meja kayu menampilkan Node.js penerima code dalam lingkungan editor VS Code.

Contoh Express yang berfokus pada produksi

const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = process.env.PORT || 3000;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

// Capture raw body for signature verification
app.use(
  express.json({
    verify: (req, res, buf) => {
      req.rawBody = buf;
    },
  })
);

function safeEqual(a, b) {
  const aBuf = Buffer.from(a, 'utf8');
  const bBuf = Buffer.from(b, 'utf8');
  if (aBuf.length !== bBuf.length) return false;
  return crypto.timingSafeEqual(aBuf, bBuf);
}

function verifySignature(rawBody, secret, receivedSignature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  return safeEqual(expected, receivedSignature);
}

function isFresh(timestampHeader, toleranceSeconds = 300) {
  const timestamp = Number(timestampHeader);
  if (!Number.isFinite(timestamp)) return false;

  const now = Math.floor(Date.now() / 1000);
  return Math.abs(now - timestamp) <= toleranceSeconds;
}

app.post('/webhooks/example', async (req, res) => {
  const signature = req.get('x-webhook-signature');
  const timestamp = req.get('x-webhook-timestamp');

  if (!WEBHOOK_SECRET) {
    return res.status(500).send('Webhook secret is not configured');
  }

  if (!signature || !timestamp) {
    return res.status(400).send('Missing required security headers');
  }

  if (!isFresh(timestamp)) {
    return res.status(401).send('Stale webhook');
  }

  const valid = verifySignature(req.rawBody, WEBHOOK_SECRET, signature);
  if (!valid) {
    return res.status(401).send('Invalid signature');
  }

  // Acknowledge quickly
  res.status(200).send('OK');

  // Process after acknowledgement
  try {
    const event = req.body;
    console.log('Accepted event:', event.event, event.id);
    // enqueueJob(event)
  } catch (err) {
    console.error('Post-ack processing failed:', err);
  }
});

app.listen(PORT, () => {
  console.log(`Webhook receiver listening on ${PORT}`);
});

Mengapa struktur ini tetap stabil

Pilihan-pilihan di sini adalah sengaja:

  • Pengambilan tubuh asli terjadi di middleware. Hal itu mempertahankan byte asli untuk hashing.
  • Tanggal waktu di periksa sebelum logika bisnis. Tidak ada gunanya melakukan pekerjaan untuk lalu lintas yang tidak aktif.
  • Rute kembali 200 cepat. Pekerjaan yang berlangsung lama harus dimasukkan ke dalam antrian atau tugas latar belakang.
  • Pengolahan setelah konfirmasi diisolasi. Meskipun logika downstream gagal, jalur penerima tetap kecil.

Rahasia adalah titik lemah dalam banyak implementasi webhook. Jangan simpan mereka di sumber, jangan tempel mereka ke fixture uji, dan jangan ulangi mereka di log. Jika Anda membutuhkan proses yang lebih luas seputar rotasi dan pengelolaan CI, panduan Capgo tentang manajemen rahasia di pipa CI/CD menutupi sisi operasional dengan baik. Langkah-langkah singkat membantu jika Anda ingin melihat bagian-bagian yang bergerak secara langsung:

Apa yang saya ubah untuk sistem hidup

Untuk integrasi penyedia yang sebenarnya, saya akan menambahkan deduplikasi ID event di penyimpanan persisten, log struktur dengan ID permintaan, dan antrian di belakang jalur pengakuan. Saya juga akan menghindari endpoint umum yang tunggal jika penyedia yang berbeda menggunakan format tanda tangan yang berbeda. Pengelola handler yang terpisah lebih mudah untuk dipahami dan lebih sulit untuk rusak.

Membangun Penerima Webhook di Python

Flask adalah pilihan yang baik untuk contoh webhook yang bersih karena pengelolaan permintaan yang eksplisit dan Python's library standar sudah memberikan apa yang Anda butuhkan untuk HMAC.

Hal utama yang perlu diingat sama seperti di Node. Verifikasi terhadap byte permintaan asli, bukan kamus JSON yang diparsing.

Contoh Flask dengan pengecekan tanda tangan dan timestamp

Detail Flask yang spesifik yang berpengaruh

import os
import time
import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = os.environ.get("WEBHOOK_SECRET", "")

def is_fresh(timestamp_header, tolerance_seconds=300):
    try:
        timestamp = int(timestamp_header)
    except (TypeError, ValueError):
        return False

    now = int(time.time())
    return abs(now - timestamp) <= tolerance_seconds

def verify_signature(raw_body, secret, received_signature):
    expected = hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(expected, received_signature)

@app.route("/webhooks/example", methods=["POST"])
def webhook():
    if not WEBHOOK_SECRET:
        return "Webhook secret is not configured", 500

    signature = request.headers.get("X-Webhook-Signature")
    timestamp = request.headers.get("X-Webhook-Timestamp")

    if not signature or not timestamp:
        return "Missing required security headers", 400

    if not is_fresh(timestamp):
        return "Stale webhook", 401

    raw_body = request.get_data()

    if not verify_signature(raw_body, WEBHOOK_SECRET, signature):
        return "Invalid signature", 401

    payload = request.get_json(silent=True) or {}

    # Acknowledge receipt
    response = jsonify({"status": "ok"})

    # In production, queue payload here instead of heavy sync work
    print("Accepted event:", payload.get("event"), payload.get("id"))

    return response, 200

if __name__ == "__main__":
    app.run(port=5000, debug=True)

Rahasia adalah titik lemah dalam banyak implementasi webhook. Jangan simpan mereka di sumber, jangan tempel mereka ke fixture uji, dan jangan ulangi mereka di log. Jika Anda membutuhkan proses yang lebih luas seputar rotasi dan pengelolaan CI, panduan __CAPGO_KEEP_0__ tentang manajemen rahasia di pipa CI/CD menutupi sisi operasional dengan baik.

request.get_data() di sini adalah panggilan kunci. Ini memberikan Anda byte mentah dari tubuh. Jika Anda langsung melompat ke request.json, Anda sudah melewati garis di mana kesalahan tanda tangan menjadi bingung.

Catatan implementasi beberapa:

  • Gunakan hmac.compare_digest sebaliknya dari kesamaan biasa.
  • Tangani header yang hilang sebagai gagal klien dan tolak awal.
  • Gunakan silent=True untuk parsing JSON jika Anda ingin mengontrol pengelolaan kesalahan daripada membiarkan Flask menerbitkan.
  • Tinggalkan rute tipis. Enkripsi pekerjaan jika payload memicu apa pun yang mahal.

Don’t debug kesalahan tanda tangan dengan melembutkan pengujian keamanan. Debug mereka dengan mencetak secara tepat apa saja byte yang Anda hash dan apa saja format yang diharapkan penyedia.

Di mana tim biasanya terjebak

Jalur gagal yang umum adalah melakukan pengujian dengan tubuh JSON yang dibangun tangan, kemudian beralih ke penyedia nyata dan menemukan bahwa tanda tangan tidak lagi cocok. Biasanya berarti salah satu dari tiga hal: penyedia menandatangani amplop yang timestamped, tanda tangan dikodekan berbeda dari yang Anda asumsikan, atau middleware mengubah tubuh sebelum verifikasi.

Ketika itu terjadi, hentikan mengubah kriptografi code secara acak. Tangkap header mentah dan tubuh mentah, reproduksi hash dalam skrip terisolasi yang sangat kecil, dan baru kemudian masukkan kembali ke dalam jalur Flask.

Membangun Penerima Webhook di Go

Go adalah pilihan yang bagus untuk penerima webhook karena library standar sudah cukup. Anda tidak memerlukan framework untuk mendapatkan handler kecil yang dapat diandalkan, dan code mudah untuk menjaga kejujuran.

Satu hal yang perlu diwaspadai adalah pengelolaan tubuh. r.Body adalah aliran. Baca sekali, hash byte yang Anda dapat, dan kemudian unmarshalling dari byte yang sama.

Contoh library standar

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"crypto/subtle"
	"encoding/hex"
	"encoding/json"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"
)

type WebhookPayload struct {
	Event string          `json:"event"`
	ID    string          `json:"id"`
	Data  json.RawMessage `json:"data"`
}

func isFresh(timestampHeader string, toleranceSeconds int64) bool {
	ts, err := strconv.ParseInt(timestampHeader, 10, 64)
	if err != nil {
		return false
	}

	now := time.Now().Unix()
	diff := now - ts
	if diff < 0 {
		diff = -diff
	}

	return diff <= toleranceSeconds
}

func verifySignature(rawBody []byte, secret string, received string) bool {
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write(rawBody)
	expected := hex.EncodeToString(mac.Sum(nil))

	if len(expected) != len(received) {
		return false
	}

	return subtle.ConstantTimeCompare([]byte(expected), []byte(received)) == 1
}

func webhookHandler(secret string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
			return
		}

		signature := r.Header.Get("X-Webhook-Signature")
		timestamp := r.Header.Get("X-Webhook-Timestamp")

		if signature == "" || timestamp == "" {
			http.Error(w, "missing required security headers", http.StatusBadRequest)
			return
		}

		if !isFresh(timestamp, 300) {
			http.Error(w, "stale webhook", http.StatusUnauthorized)
			return
		}

		rawBody, err := io.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "failed to read body", http.StatusBadRequest)
			return
		}

		if !verifySignature(rawBody, secret, signature) {
			http.Error(w, "invalid signature", http.StatusUnauthorized)
			return
		}

		var payload WebhookPayload
		if err := json.Unmarshal(rawBody, &payload); err != nil {
			http.Error(w, "invalid json", http.StatusBadRequest)
			return
		}

		w.WriteHeader(http.StatusOK)
		w.Write([]byte("OK"))

		log.Printf("accepted event=%s id=%s", payload.Event, payload.ID)
	}
}

func main() {
	secret := os.Getenv("WEBHOOK_SECRET")
	if secret == "" {
		log.Fatal("WEBHOOK_SECRET is not set")
	}

	http.HandleFunc("/webhooks/example", webhookHandler(secret))

	log.Println("listening on :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Mengapa Go terasa solid di sini

Beberapa keuntungan yang menonjol adalah:

  • Penggunaan handler yang eksplisit. Tidak ada keajaiban middleware yang disembunyikan.
  • Membuat kode membantu di tepi. Parsing header, konversi timestamp, dan dekripsi JSON semua gagal dengan jelas.
  • Paket kriptografi standar sudah cukup. Tidak ada dependensi tambahan untuk verifikasi HMAC dasar.

Catatan Operasional

Jika volume webhook tumbuh, model koncurrency Go memberikan ruang untuk membagi pekerjaan latar belakang tanpa mengubah pintu masuk HTTP. Bahkan saat itu, tetaplah menjaga penerimaan sempit. Terima, validasi, konfirmasi, lalu tukarkan.

Pengguna Webhook Go yang kuat biasanya tetap sederhana. Mereka tidak mencampur verifikasi transportasi dengan logika bisnis, dan mereka tidak melakukan pekerjaan basis data berat sebelum respons dikembalikan.

Teknik Debugging yang Paling Penting

Biasanya, bug webhook muncul sebagai pesan dukungan, bukan stack trace. Provider mengatakan mereka telah mengirimkan event. Endpoint Anda mengatakan tidak ada yang mencapai aplikasi, atau verifikasi tanda tangan gagal pada permintaan yang terlihat valid pada pandangan pertama. Pada titik itu, debugging adalah tentang merekonstruksi pertukaran HTTP yang tepat, byte per byte, dan membuktikan di mana itu gagal.

Daftar Lima Alat dan Teknik Debugging Webhook yang Paling Penting dalam Lingkungan Pengembangan Perangkat Lunak.

Kit Debugging yang Praktis

Mulai dengan format kabel.

Jika periksa tanda tangan gagal, tangkap tubuh permintaan mentah secara tepat seperti yang diterima, bersama dengan header yang digunakan untuk verifikasi. Pada kenyataannya, bug seringkali membosankan. Suatu kerangka memproses JSON sebelum hashing, suatu proxy mengubah encoding, atau ulang coba tes melewatkan timestamp asli header. Mencatat objek yang diproses tidak cukup. Anda memerlukan byte asli dan input verifikasi.

Alat-alat ini membantu mengisolasi masalah cepat:

  • Perekaman permintaan mentahLog header, jenis konten, panjang konten, dan tubuh yang tidak dimodifikasi selama penyelidikan.
  • Endpoint pemeriksaan permintaanJasa seperti webhook.site membantu memastikan apa yang dikirimkan pengirim.
  • Tunneling lokal. ngrok dan alat-alat serupa memungkinkan Anda menguji terhadap penerima lokal sambil menjaga penyedia dalam jalur.
  • Ulang coba manualRekonstruksi permintaan dengan curl atau Postman menggunakan tubuh dan header yang sama. Itu adalah cara tercepat untuk memastikan apakah code atau payload penyedia adalah masalah.
  • Catatan pengiriman penyedia. Dashboard pengirim sering kali mencakup kode respons, riwayat ulang, dan identifikasi permintaan yang dapat Anda sesuaikan dengan log Anda.

Polanya penting. Mulai dari luar ke dalam. Pertama, verifikasi apakah penyedia mengirimkan apa yang Anda harapkan. Kemudian verifikasi apakah server Anda menerima byte yang sama. Kemudian verifikasi apakah code menghash byte yang sama dengan aturan rahasia dan timestamp yang sama.

Pengaturan log yang sebenarnya membantu

Log webhook yang baik harus menjawab tiga pertanyaan dalam satu pencarian:

Pertanyaan Bidang log yang berguna
Apakah permintaan sampai? rute, metode, received_at
Mengapa ditolak? missing_header, stale_timestamp, signature_failed
Apakah saya bisa menghubungkannya kemudian? __CAPGO_KEEP_0__

Apa yang membantu di sistem nyata adalah lapangan keempat. request_id Tambahkan sebuah lokal __CAPGO_KEEP_1__ yang dibuat oleh penerima Anda sehingga Anda bisa mengikuti permintaan melalui log aplikasi, antrian, dan pekerja.

Pilihlah dengan selektif apa yang disimpan. Tidak pernah log rahasia. Hindari membuang muatan produksi penuh jika mereka termasuk data pelanggan, token akses, atau detail tagihan. Pola yang lebih aman adalah log metadata plus hash tubuh singkat. Ini masih memungkinkan Anda membandingkan ulang dan memastikan apakah dua pengiriman identik.

Reproduksi gagal dengan input asli

Bagian ini adalah bagian dasar tutorial yang dilewati. Jika Anda tidak bisa merekam kembali permintaan gagal secara tepat, Anda hanya menebak.

Simpan webhook gagal sebagai:

  • byte byte tubuh mentah
  • semua header terkait tanda tangan
  • waktu timestamp permintaan
  • jenis konten
  • ID penggunaan provider

Lalu ulangi kembali melawan endpoint pengujian. Jika ulangan berhasil, bandingkan apa saja yang berubah selama transit. Pengganggu umum termasuk middleware yang memnormalisasi tubuh permintaan, kesalahan pengkodean karakter, dan balancer beban yang menghilangkan atau menulis ulang header.

For broader release and mobile transport troubleshooting, the same debugging discipline shows up in Capgo’s guide to Untuk troubleshooting rilis lebih luas dan transportasi seluler, disiplin debugging yang sama muncul dalam panduan Capacitor untukalat-alat debugging update OTA di code

. Transportasi berbeda, pelajaran yang sama. Tangkap path permintaan asli sebelum mengubah aplikasi code.

Jika verifikasi tanda tangan gagal, inspect byte-raw, header yang tepat digunakan dalam verifikasi, dan nilai timestamp sebelum menyentuh kriptografi __CAPGO_KEEP_0__.

Daftar Periksa untuk Webhook yang Siap Produksi

Pengelola webhook biasanya terlihat baik di pengujian sampai hujan ulang permintaan, payload yang rusak, atau kesalahan tanda tangan pada pukul 2 pagi. Batas produksi lebih tinggi. Penerima harus menolak permintaan palsu, menerima ulang permintaan yang sah, dan memberikan signal operator cukup untuk debugging gagal tanpa mengungkapkan data sensitif.

  • Pengecekan Keamanan dan KorrectifPeriksa setiap tanda tangan permintaan
  • . URL endpoint bocor. URL pengujian dibagikan di obrolan. Verifikasi tanda tangan adalah kontrol yang memberitahu Anda bahwa pengirim tahu rahasia yang disepakati.','Tolak permintaan lama']}. Tanda tangan yang valid pada payload lama masih dapat direplay. Pastikan toleransi timestamp sesuai dengan model ulang yang disediakan oleh penyedia.
  • Hashkan tubuh mentah, bukan JSON yang diparsing. Middleware dapat mengurutkan kunci, mengatur spasi, atau mengubah encoding. Verifikasi harus berjalan melawan byte yang tepat yang datang.
  • Simpan rahasia tanda tangan di luar code. Variabel lingkungan adalah dasar. Manajer rahasia lebih baik jika Anda memutar kredential secara berkala atau menjalankan di beberapa lingkungan.
  • Kosongkan pada kesalahan autentikasi. Jika header tanda tangan hilang, rusak, atau menggunakan skema yang tidak terduga, tolak permintaan dan catat alasan.

Periksa keandalan

  • Konfirmasi cepat. Penyedia biasanya menganggap 2xx sebagai kesuksesan, jadi validasi permintaan, simpan apa yang Anda butuhkan, dan pindahkan pekerjaan yang lambat ke antrian atau pekerja.
  • Buat handler yang idempoten. Acara yang sama mungkin datang lebih dari sekali. Pindahkan efek sampingan ke ID acara, ID pengiriman, atau identifier penyedia stabil lainnya.
  • Kembalikan kode kesalahan yang dapat diprediksi. Gunakan 400 untuk input yang rusak, 401 atau 403 untuk verifikasi gagal, dan 5xx hanya ketika sistem Anda adalah masalah. Hal ini membuat perilaku ulang penyedia lebih mudah dipahami.
  • Tetapkan batasan sebelum memproses. Batasi ukuran permintaan Cap, jenis konten, dan jumlah header awal. Hal ini mencegah endpoint webhook menjadi lubang pengambilan umum.
  • Tetapkan kontrak sempit. Terima hanya bidang dan jenis acara yang Anda dukung. Pemrosesan longgar terasa nyaman pada awalnya dan menjadi mahal selama perubahan penyedia API.

Periksa observabilitas

Operasi webhook yang baik terlihat membosankan. Tim dapat menjawab tiga pertanyaan dengan cepat: Apakah kita menerima? Apakah kita memverifikasi? Apakah proses downstream berhasil?

Gunakan standar:

  • Tangani penerimaan, verifikasi, dan pengolahan sebagai hasil yang terpisah.
  • Catat ID permintaan, ID event, status tanda tangan, dan perbedaan waktu timestamp.
  • Ukur delay antrian, latensi handler, dan volume ulang.
  • Tetapkan jalur ulang aman untuk alur kerja staging atau redelivery.
  • Peringatkan perubahan pola, seperti lonjakan pada gagal tanda tangan atau pengiriman duplikat.

Capgo adalah contoh yang berguna dari titik operasional yang lebih luas. Ini termasuk alat sekitar pengiriman rilis dan observabilitas dalam alur kerja update, serta bagian dari ekosistemnya juga menyentuh alur terkait webhook. Pelajaran ini sangat praktis. Sistem pengiriman membutuhkan visibilitas dari penerimaan hingga selesai.

Jika sebuah tim menutupi cek-cek di atas, penerima webhook biasanya dalam kondisi baik untuk produksi. Jika ada item yang hilang, celah tersebut cenderung muncul selama insiden, bukan selama demo.

Frequently Asked Questions Tentang Webhook

Apa status code yang harus saya kembalikan?

Kembalikan sebuah 2xx ketika Anda telah menerima webhook. Jika validasi gagal, kembalikan error klien atau autentikasi yang sesuai dengan kegagalan, seperti 400 untuk input yang rusak atau 401 untuk data autentikasi yang tidak valid. Jaga logika konsisten sehingga dashboard penyedia lebih mudah dipahami.

Apakah saya harus memproses webhook secara sinkron?

Biasanya tidak. Validasikan, konfirmasikan, lalu kirimkan pekerjaan sebenarnya ke antrian atau pekerja latar belakang. Hal ini menjaga jalur pengiriman cepat dan mengurangi ulang coba yang disebabkan oleh proses downstream yang lambat.

Bagaimana saya harus menghadapi ulang coba?

Anggap mereka akan terjadi. Bangun ketahanan idempotensi ke dalam handler Anda sehingga menerima event yang sama lagi tidak akan menghasilkan efek sampingan yang berulang. ID event atau ID pengiriman penyedia biasanya adalah anker yang biasa digunakan untuk itu.

Apa jika event datang dalam urutan yang salah?

Desain handler untuk toleran urutan ketika Anda bisa. Jika proses bisnis memerlukan urutan, simpan cukup state untuk mendeteksi transisi yang ketinggalan waktu daripada mengasumsikan urutan pengiriman menggambarkan urutan event.

Bagaimana saya menghadapi perubahan versi webhook?

Versi logika handler Anda secara sengaja. Jaga parsing penyedia yang spesifik terisolasi, hindari menyebarkan asumsi payload melalui kodebase Anda, dan tambahkan tes dengan contoh yang sebenarnya sebelum meluncurkan dukungan untuk format baru.


If tim Anda mengirimkan aplikasi Capacitor atau Electron, Capgo perlu diketahui karena alasan yang terkait. Ini memberikan tim cara yang terkendali untuk mengirimkan pembaruan web yang ditandatangani, mengamati perilaku peluncuran, dan mengembalikan dari insiden tanpa menunggu tinjauan toko aplikasi, yang sesuai dengan insting insinyur yang sama di balik desain webhook yang solid: validasi input, jaga jalur rilis teramati, dan buat pemulihan cepat.

Pembaruan langsung untuk aplikasi Capacitor

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan pembaruan di latar belakang sementara perubahan native tetap dalam jalur review normal.

Mulai Sekarang

Terbaru dari Blog Kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk menciptakan aplikasi mobile yang benar-benar profesional.