Kanıt entegrasyon rehberi
Kanıt, kullanıcılarının Netflix gibi platformlardaki verilerini, şifrelerini ya da hesaplarını görmeden doğrulamanı sağlar. Sana sadece istediğin alanlar ve bunların attestor imzalı kanıtı döner.
verifyUrl ve listenToken alır.verifyUrl'i açar ve listenToken ile socket'ten dinlemeye başlar.redirectUrl ile uygulamana döner.Hesap ve uygulama
- Geliştirici hesabı oluştur.
- Panelde Yeni uygulama de.
App Key,App SecretveWebhook Secretsadece bu anda gösterilir: kopyala, backend'inin ortam değişkenlerine koy. - Uygulama sayfasında İstenebilecek veriler bölümünden istediğin veri türlerini aç (ör. Netflix · İzleme geçmişi).
- İstersen Webhook URL gir.
Logo ve marka
Kullanıcı doğrulama sayfasında senin uygulama adını ve logonu görür: "Uygulaman, Netflix hesabındaki izleme geçmişini doğrulamak istiyor". Ayarlamak için:
- Panel → uygulamanı seç.
- Genel kartında Uygulama adını düzenle.
- Logo bölümünden kare bir PNG, JPG ya da WEBP yükle (en fazla 512KB, önerilen 256×256).
Güvenlik için SVG kabul edilmez. Dosya türü uzantıya değil, içeriğine bakılarak kontrol edilir.
1. Backend: oturum aç
Her doğrulama için backend'inde bir oturum aç. Dönen verifyUrl ve listenToken'ı uygulamana (web/mobil) gönder. Oturum 15 dakika geçerlidir ve tek kullanımlıktır.
npm install @kanit/sdk
import { KanitClient } from '@kanit/sdk'
const kanit = new KanitClient({
appKey: process.env.KANIT_APP_KEY,
appSecret: process.env.KANIT_APP_SECRET,
baseUrl: 'https://portal.vuid.app',
})
// ör. POST /api/kanit/start (kendi endpoint'in)
const session = await kanit.createSession({
provider: 'netflix',
claim: 'viewing-history',
reference: user.id, // opsiyonel, sonuçta geri döner
redirectUrl: 'benimapp://kanit-tamam', // opsiyonel: mobil deep link ya da https
})
res.json({
sessionId: session.sessionId,
verifyUrl: session.verifyUrl,
listenToken: session.listenToken,
})2. Sonucu al
Sonucu almanın üç yolu var, birlikte de kullanılabilir:
| Yol | Nerede | Ne zaman kullan |
|---|---|---|
| Socket | Web / mobil uygulama | Ekranda anında "doğrulandı" göstermek için. Olaylar |
| Webhook | Backend | İndirim, rozet gibi kalıcı işlemler için. İmzalıdır. Doğrulama |
| GET /v1/sessions/:id | Backend | Webhook yoksa ya da tekrar kontrol için. |
Web sitesi
Masaüstünde doğrulama yeni sekmede, telefonda aynı sekmede açılır.
import { listenSession, openVerification } from '@kanit/sdk/browser'
const session = await fetch('/api/kanit/start', { method: 'POST' }).then(r => r.json())
openVerification(session.verifyUrl)
const stop = listenSession({
baseUrl: 'https://portal.vuid.app',
sessionId: session.sessionId,
listenToken: session.listenToken,
onStatus: e => console.log('durum:', e.status), // starting, login, select, proving
onCompleted: e => showSuccess(e.fields), // ör. { title, series, date }
onFailed: e => showError(e.error),
})Mobil uygulama
Mobilde akış aynıdır, üç ek nokta var:
- Oturumu backend'in açar. App Secret uygulamanın içine asla konmaz.
verifyUrl'i uygulama içi tarayıcıda aç. iOS'taASWebAuthenticationSession, Android'de Custom Tabs. WebView kullanma: sayfanın güvenliği için gerçek tarayıcı gerekir.redirectUrl'e uygulamanın deep link'ini ver (ör.benimapp://kanit-tamam). Kullanıcı bitirince uygulamana döner. URL'e?kanit_session=…&kanit_status=completed|failedeklenir.
Sonucu socket ile anında dinleyebilir ya da kullanıcı döndüğünde backend'ine sorabilirsin.
// npm install @kanit/sdk socket.io-client react-native-inappbrowser-reborn
import InAppBrowser from 'react-native-inappbrowser-reborn'
import { listenSession } from '@kanit/sdk/browser'
async function verifyNetflix() {
// backend'in createSession({ ..., redirectUrl: 'benimapp://kanit-tamam' }) yapar
const s = await fetch('https://senin-backend.com/api/kanit/start', { method: 'POST' })
.then(r => r.json())
const stop = listenSession({
baseUrl: 'https://portal.vuid.app',
sessionId: s.sessionId,
listenToken: s.listenToken,
onCompleted: e => setVerified(e.fields),
onFailed: e => Alert.alert('Doğrulanamadı', e.error ?? ''),
})
// doğrulama bitince 'benimapp://kanit-tamam?...' ile kendiliğinden kapanır
await InAppBrowser.openAuth(s.verifyUrl, 'benimapp://kanit-tamam', {
ephemeralWebSession: true,
})
}Socket olayları
Socket.IO kullanılır. Her dilde resmi istemcisi var (JS, Swift, Kotlin/Java, Dart, Python…). Bağlantı adresi: https://portal.vuid.app/sessions (namespace /sessions, transport: websocket).
Dinlemeye başla
Bağlanınca listen gönder. Ack olarak { ok: true } döner. Geç bağlansan bile o anki durum hemen gelir.
socket.emit('listen', { sessionId, listenToken }, ack => { /* { ok: true } */ })Gelen olay: status
{
"sessionId": "e8205...",
"status": "completed",
"reference": "user-42",
"step": { "name": "generating-zk-proofs", "proofsDone": 2, "proofsTotal": 4 }, // sadece proving'de
"fields": { "movieID": "81257204", "title": "Season 1: ...", "series": "Wednesday", "date": "10/16/26" },
"proof": { ... }, // attestor imzalı kanıt
"error": null
}| status | Anlamı |
|---|---|
created | Oturum açıldı, kullanıcı sayfayı henüz açmadı |
starting | Güvenli tarayıcı açılıyor |
login | Kullanıcı platforma giriş yapıyor |
select | Kullanıcı paylaşacağı içeriği seçiyor |
proving | Kanıt üretiliyor (step ile ilerleme) |
completed | Bitti: fields ve proof dolu |
failed / expired | Başarısız ya da 15 dakika doldu: error |
Webhook
Uygulama ayarlarına Webhook URL girersen, oturum bitince (session.completed /session.failed) oraya POST yapılır. Başarısız olursa 3 kez denenir.
Her isteğin X-Kanit-Signature: t=<unix>,v1=<imza> başlığı vardır. İmza: HMAC_SHA256(webhookSecret, t + "." + hamGövde). 5 dakikadan eski isteği reddet.
import express from 'express'
import { verifyWebhook } from '@kanit/sdk'
// ham gövde gerekli: express.json() değil express.text()
app.post('/webhooks/kanit', express.text({ type: '*/*' }), (req, res) => {
try {
const event = verifyWebhook(req.body, req.get('x-kanit-signature'), process.env.KANIT_WEBHOOK_SECRET)
if (event.status === 'completed') grantDiscount(event.reference, event.fields)
res.sendStatus(200)
} catch {
res.sendStatus(400)
}
})HTTP API
| Uç nokta | Yetki | Açıklama |
|---|---|---|
POST /v1/sessions | App Key + Secret | Oturum aç. Gövde: provider, claim, ops. reference, redirectUrl |
GET /v1/sessions/:id | App Key + Secret | Oturumun durumu, fields ve proof |
GET /v1/attestor | — | Kanıtları imzalayan attestor adresi (bağımsız doğrulama için) |
GET /providers | — | Platformlar, veri türleri ve dönen alanlar |
Yetki başlıkları: X-App-Key, X-App-Secret. Hatalar { statusCode, message } döner. 403: veri türü uygulamada açık değil ya da aylık kota doldu.
Veri türleri
| provider | claim | Dönen alanlar |
|---|---|---|
netflix | viewing-historyİzleme geçmişi | movieIDtitleseriesdatewatchedAt |
netflix | viewing-history-allİzleme geçmişi (tümü) | history |
netflix | my-listListem | movieIDtitle |
prime-video | Yakında | |
disney-plus | Yakında | |
hbo-max | Yakında | |
Güvenlik
- Kullanıcının şifresi, oturum çerezi ve diğer verileri sana hiçbir zaman gelmez, bizde de saklanmaz.
- Her doğrulama tek kullanımlık, izole bir tarayıcıda yapılır. İş bitince tarayıcı ve profili silinir.
- Kanıt, oturuma bağlıdır (
sessionId): başka bir oturumda tekrar kullanılamaz. - Gelen her kanıt, attestor imzası ve veri türünün izin verdiği alanlar açısından kontrol edilir. Sadece tanımlı alanlar sana iletilir.
listenTokensadece o oturumu dinleyebilir. App Secret yalnızca backend'de kalmalı.