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:
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:
{
"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ık | Açıklama |
|---|---|
X-GTI-Event | Olayın türü. |
X-GTI-Timestamp | İsteğin gönderildiği an (Unix saniye). |
X-GTI-Signature | Gö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:
t=1756713600,v1=5f3a9c...v1, şu değerin HMAC-SHA256 özetidir:
{timestamp}.{ham gövde}İmzalama anahtarını GlobalTrustID sağlar.
Node.js#
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#
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#
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.