İçeriğe geç
GlobalTrustIDdocs

Webhooks

Doğrulama sonucunu sunucunuza anında iletmek ve imzayı doğrulamak.

Webhook, doğrulama sonucu hazır olduğunda sizin sunucunuza yaptığımız bir POST isteğidir. Kullanıcı tarayıcıyı kapatsa bile sonuç size ulaşır.

Kurulum#

Oturumu açarken webhook_url verin:

Terminal
curl -X POST https://api.globaltrust.id/v1/verification/session \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "scope": ["identity.first_name", "identity.last_name"],
    "webhook_url": "https://sizin-siteniz.com/gti/webhook"
  }'

Adresiniz https olmalı ve herkese açık şekilde erişilebilir olmalıdır.

Gelen istek#

Gövde, oturumun sonucudur:

JSON
{
  "session_id": "01J8ZQ4X7K9M2N3P4Q5R6S7T8U",
  "status": "approved",
  "scope": ["identity.first_name", "identity.last_name"],
  "identity": {
    "identity.first_name": "Ayşe",
    "identity.last_name": "Yılmaz"
  }
}

Başlıklar:

BaşlıkAçıklama
X-GTI-EventOlayın türü.
X-GTI-Timestampİsteğin gönderildiği an (Unix saniye).
X-GTI-SignatureGövdenin HMAC imzası.

İmzayı doğrulayın#

Bu adımı atlamayın. Webhook adresiniz herkese açıktır; imzayı doğrulamadan gelen gövdeye güvenirseniz, size sahte bir "onaylandı" gönderen herkes kimlik doğrulamasını atlatmış olur.

İmza şu biçimdedir:

Çıktı
t=1756713600,v1=5f3a9c...

v1, şu değerin HMAC-SHA256 özetidir:

Çıktı
{timestamp}.{ham gövde}

İmzalama anahtarını GlobalTrustID sağlar.

Node.js#

JavaScript
const crypto = require("crypto");

function dogrula(imzaBasligi, timestamp, hamGovde, sir) {
  const beklenen = crypto
    .createHmac("sha256", sir)
    .update(timestamp + "." + hamGovde)
    .digest("hex");

  const gelen = (imzaBasligi.match(/v1=([a-f0-9]+)/) || [])[1] || "";

  // Sabit zamanlı karşılaştırma: baytları tek tek sızdıran bir karşılaştırma
  // imzanın tahmin edilmesine yarar.
  const a = Buffer.from(beklenen, "hex");
  const b = Buffer.from(gelen, "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Go#

Go
func dogrula(imzaBasligi, timestamp string, hamGovde, sir []byte) bool {
    mac := hmac.New(sha256.New, sir)
    mac.Write([]byte(timestamp))
    mac.Write([]byte("."))
    mac.Write(hamGovde)
    beklenen := hex.EncodeToString(mac.Sum(nil))

    _, gelen, _ := strings.Cut(imzaBasligi, "v1=")
    return hmac.Equal([]byte(beklenen), []byte(gelen))
}

Python#

Python
import hmac, hashlib, re

def dogrula(imza_basligi: str, timestamp: str, ham_govde: bytes, sir: bytes) -> bool:
    beklenen = hmac.new(sir, timestamp.encode() + b"." + ham_govde, hashlib.sha256).hexdigest()
    eslesme = re.search(r"v1=([a-f0-9]+)", imza_basligi)
    return bool(eslesme) and hmac.compare_digest(beklenen, eslesme.group(1))

Zaman damgasını da kontrol edin#

İmza doğru olsa bile çok eski bir isteği kabul etmeyin. Saldırgan geçerli bir isteği kaydedip sonra tekrar gönderebilir (replay). 5 dakikadan eski istekleri reddetmek makul bir sınırdır.

Yanıt vermeniz gerekenler#

  • Başarılıysa 2xx dönün.
  • Gövdeye ihtiyacımız yok, boş yanıt yeterlidir.
  • Hızlı yanıt verin. Ağır işleri (e-posta gönderme, rapor üretme) kuyruğa alın; webhook isteğini bekletmeyin.

2xx dışında bir yanıt alırsak veya bağlantı kurulamazsa yeniden deneriz.

Aynı olayın iki kez gelmesi#

Yeniden deneme yüzünden aynı sonuç size iki kez ulaşabilir. Bu yüzden işleyicinizi idempotent yazın: session_id'yi kaydedin ve daha önce işlediğiniz bir oturum geldiğinde 2xx dönüp hiçbir şey yapmayın.

Test etme#

Geliştirme sırasında yerel sunucunuz internete kapalıdır. ngrok gibi bir tünel aracıyla geçici bir genel adres alıp webhook_url olarak verebilirsiniz.