Ana içeriğe geç

00 · AUTH — Açılış Sözleşmesi

Görev: Uygulama açıldığında kimliği doğrular, güncel config versiyonlarını ve bir token döndürür; açılışta ne yapılacağına dair karar (decision) verir.

Ne zaman çalışır: Her uygulama açılışında — ilk çalıştırmada ve sonrasında her seferinde.

Bu dosyayı örnek istek/yanıtlarla birlikte okuyun: JSON'lar doldurulmuş örnektir; bölümdeki tablolar alanların anlamını anlatır.


1. Genel Bakış​

AUTH, döngünün ilk ve her seferinde çalışan adımıdır. SDK sunucuya iki şey gönderir:

  • Kimlik → apiKey + packageName + platform + consentId
  • Cihazda önbelleklediği mevcut durumu → localState (kurulu versiyonlar + önceki onay haritası)

Sunucu karşılığında üç şey döndürür:

  • Versiyonlar → schemaVersion / uiVersion / legalVersion / contentVersion
  • Token → oturum bazlı config token'ı (tokenExpiresIn saniye ile geçerlilik)
  • Karar → decision: config yenileme mi, tekrar sor (reprompt) mu, yoksa sessizce devam mı?

Tasarım felsefesi: AUTH hafif ve hızlı tutulur. Güncel config (tema, ekranlar, gruplar, metinler — büyük gövde) yalnızca değiştiğinde, decision.updateRequired === true olduğunda, bir sonraki adım olan 01 · GET /config ile çekilir. İçerik değişmiyorsa config hiç transfer edilmez → açılış hızlı, veri tasarruflu, gecikme düşük.


2. İki Aşamalı Açılış Akışı​

┌──────────────┐ kimlik + localState ┌──────────────┐
│ SDK (App) │ ─────────────────────▶ │ SUNUCU │
│ │ ◀───────────────────── │ │
└──────────────┘ versiyon + token + decision └──────────────┘
│
decision.updateRequired ?
┌───────────────┴───────────────┐
│ TRUE │ FALSE
▼ ▼
GET /config (01) Mevcut config'i
token ile tam config indir, cihazdaki önbellekten
parse et, önbelleğe yaz, kullan; sürüye devam et
UI'ı yeniden kur
│
▼
decision.retriggerRequired /
showConsentOnLaunch → onay ekranını göster mi?
AdımKoşulSDK davranışı
1 — AUTH (bu sözleşme)Her açılıştaKimlik + localState gönder; versiyon + token + decision al
2 — GET /configdecision.updateRequired === true iseToken ile tam config indir, parsel et, önbelleğe yaz, UI'ı yeniden kur
3 — Onay kararıshowConsentOnLaunch veya retriggerRequired true iseOnay ekranını (banner/manager) göster; aksi halde sessiz devam

3. Endpoint & Güvenlik​

3.1 Endpoint​

ÖzellikDeğer
MethodPOST
Path/v2/consent/{consentId}/auth
Base URL{{SDK_BASE_URL}}
Gövde formatıapplication/json (UTF-8)
Timeout15 sn
IdempotentEvet — aynı istek tekrarlandığında aynı sonucu verir

3.2 Güvenlik (imza ile sahte/replay istek koruması)​

Kimlik doğrulaması yalnız apiKey ile değil, HMAC imza + nonce + zaman damgası üçlüsüyle yapılır. İstek şunları taşır:

HeaderDeğer / Formül
Content-Typeapplication/json
X-Consent-SDK-KeyapiKey (body'deki apiKey'ye alternatif; üretimde header tercih edilir)
X-Consent-SignatureHMAC-SHA256(apiKey, packageName + platform + requestTimestamp + nonce) — hex kodlanmış
X-Request-Timestampepoch milliseconds
X-NonceTek kullanımlık rastgele string
  • Algoritma: HMAC-SHA256
  • İmza girdisi (canonical): packageName + platform + requestTimestamp + nonce
  • Replay penceresi: ±300 sn. Penceresi dışındaki timestamp veya tekrar eden nonce → 401 REPLAY_DETECTED.

AUTH ve POST_CONSENT yazma/durum değiştirici sözleşmeler olduğu için imza/nonce/timestamp zorunludur. (GET /config bir okuma işlemidir; orada imza yerine yalnız token kullanılır — 01 · GET /config §3.)


4. İstek (request)​

Uygulamanın gönderdiği gövde. Kimlik alanları zorunludur; geriye kalanlar isteğe bağlıdır ama kararın doğruluğunu artırır. camelCase zorunludur.

AlanTipZorunluAçıklama
apiKeystringEvetUygulamanın gizli API anahtarı (kendi Apps Console'undan). Yanlış/çözülmüş anahtar → 401 INVALID_API_KEY.
consentIdstringEvetOnay kaydının benzersiz kimliği (ör. ck_mobildev_0001). Hangi consent setinin çözüleceğini belirler. Path'teki {consentId}'yle birebir aynı olmalıdır.
packageNamestringEvetPaket/identifier. Android: reverse-domain (com.mobildev.app); iOS: bundle id (com.mobildev.ios). apiKey'nin bu package'a tanımlı olup olmadığı doğrulanır; uyuşmazlık → 403 PACKAGE_MISMATCH.
platformenum iOS | AndroidEvetHedef platform. Paket formatı, platform bazlı davranış (örn. iOS ATT) ve şema feature-gate kararı buna göre çözülür.
sdkVersionstring (semver)EvetSDK paketinin sürümü. schemaVersion ile birlikte feature-gate kararında kullanılır; eski SDK yeni şemayı çözemiyorsa uyumlu config setine yönlendirilir.
appVersionstring (semver)HayırMüşteri uygulamanın sürümü. Telemetri/korelasyon için; auth kararını doğrudan etkilemez.
buildNumberintegerHayıriOS CFBundleVersion / Android versionCode. Aynı appVersion içinde farklı build'leri ayırt eder.
localestring (BCP-47)HayırKullanıcı dili (ör. tr-TR). Config'in availableLanguages'inde varsa o dil, yoksa defaultLanguage çözülür.
deviceTimestring (ISO 8601 UTC)HayırCihaz saati. Sunucu saatiyle drift/manipülasyon kontrolü; aşırı drift → 400 CLOCK_DRIFT.
deviceobjectHayırmodel, osVersion. Hata teşhis ve uyumluluk raporlama içindir; auth kararında doğrudan kullanılmaz.
localStateobjectHayırCihazda önbelleklenen mevcut durum. Sunucunun karar üretmesinin geri beslemesidir (aşağıda detay). İlk çalıştırmada null/boş bırakılır.

4.1 localState Alt Alanları​

AlanTipAçıklama
hasConsentbooleanBu cihazda daha önce onay var mı? false = ilk açılış → ilk onay ekranı gösterilir.
installedUiVersionstring | nullÖnbellekteki UI/theme/layout versiyonu. Remote uiVersion'dan düşükse görünüm yenilenir (reprompt yok).
installedLegalVersionstring | nullÖnbellekteki legal/metin versiyonu. Remote'dan yüksekse metin yenilenir ve onay varsa reprompt.
installedContentVersionstring | nullÖnbellekteki içerik versiyonu. Remote'dan yüksekse retriggerRequired = true (içerik değişti → tekrar sor).
lastShownAtstring | null (ISO 8601)Onay ekranının son gösterildiği an. Config'de retrigger.interval tanımlıysa bu değer interval'ı aşarsa zaman bazlı reprompt devreye girer.
consentobject | nullÖnceki onay haritası. Anahtarlar groupId'lerdir (essential/functionality/targeting/tracking); değerler yalnız granted / denied. Bir sonraki adım (02 · POST_CONSENT'in localState) ile birebir aynı yapıdır — burada geri beslemesi için gönderilir.

4.2 Örnek İstek (ilki açılış — localState boş)​

{
"apiKey": "sk_live_9f2ac41ab88e3d5c7e9f",
"consentId": "ck_mobildev_0001",
"packageName": "com.mobildev.app",
"platform": "Android",
"sdkVersion": "1.4.0",
"appVersion": "2.8.0",
"buildNumber": 280,
"locale": "tr-TR",
"deviceTime": "2026-09-20T11:33:29Z",
"device": { "model": "Pixel 9", "osVersion": "Android 15" },
"localState": {
"hasConsent": false,
"installedUiVersion": null,
"installedLegalVersion": null,
"installedContentVersion": null,
"lastShownAt": null,
"consent": null
}
}

Daha sonraki açılışlarda localState dolu gelir (02 adımında sunucunun döndürdüğü localState, buraya aynen kopyalanır). Doğru retrigger kararı bu bloğun doluluğuna bağlıdır. Bu örneğin aynısı ayrıca [00-auth.request.json](./00-auth.request.json) dosyasında yer alır.


5. Yanıt (response)​

5.1 Gövde Alanları (200)​

AlanTipAçıklama
successbooleanİsteğin başarıyla tamamlandığı.
codestringDurum kodu (başarıda OK).
consentIdstringÇözülen consentId (eko; log/teşhis).
schemaVersionstringSDK feature-gate versiyonu (örn. 2.0). Eski SDK uyumlu set kullanır.
uiVersionstringMevcut UI/theme/layout versiyonu. Cihazdaki installedUiVersion'dan yüksekse görünüm yenilenir (reprompt değil, yalnız görsel).
legalVersionstringMevcut legal/metin versiyonu. Cihazdaki installedLegalVersion'dan yüksekse metin yenilenir ve onay varsa reprompt.
contentVersionstringMevcut içerik versiyonu. Cihazdaki installedContentVersion'dan yüksekse retriggerRequired = true.
contentModeenum sample | productionİçerik modu. sample → geliştirme/test verisi.
generatedAtstring (ISO 8601)Config'in sunucuda yayınlanma/üretim zamanı.
tokenstringGET /config ve POST_CONSENT'te kullanılacak imzalı, oturum bazlı token (örn. cfg_t_8a3f5c2d1e0b).
tokenExpiresInintegerToken geçerlilik süresi (saniye). Dolunca yeniden AUTH yapılır.
decisionobjectSDK'nın açılışta ne yapacağını belirten karar bloğu (aşağıda).

Versiyon modeli — üç bağımsız katman: schemaVersion (şema/SDK feature-gate) · uiVersion (görünüm) · legalVersion + contentVersion (içerik). Bu ayrım, "yalnız görsel değişti" ile "içerik/majör şema değişti" arasındaki reprompt farkını üretir: içerik veya majör şema değişimi reprompt üretir; yalnız görsel değişimi reprompt üretmez (görsel yenilenir).

5.2 decision Alt Alanları​

AlanTipAçıklama
updateRequiredbooleantrue → config yenileme gerekli; token ile GET /config yapılır.
retriggerRequiredbooleantrue → onay mevcut ama içerik/majör değişiklik var; onay ekranı yeniden gösterilir.
showConsentOnLaunchbooleanBu açılışta onay ekranının gösterilip gösterilmeyeceği. İlk çalıştırmada veya retrigger gerekliyse true; config değişimi yoksa false.
reasonsarray<enum>Kararı üreten nedenler (çeşitli olabilir). Loglama/teşhis.

reasons değerleri: FIRST_RUN, NO_CACHED_CONFIG, CONTENT_UPDATED, LEGAL_UPDATED, UI_UPDATED, INTERVAL_RETRIGGER, MAJOR_SCHEMA_CHANGE, TOKEN_EXPIRED, NO_CHANGE.

5.3 Örnek Yanıt (ilk açılış — config + onay ekranı gerekli)​

{
"success": true,
"code": "OK",
"consentId": "ck_mobildev_0001",
"schemaVersion": "2.0",
"uiVersion": "2.4",
"legalVersion": "1.0",
"contentVersion": "2",
"contentMode": "sample",
"generatedAt": "2026-09-18T10:20:00Z",
"token": "cfg_t_8a3f5c2d1e0b",
"tokenExpiresIn": 300,
"decision": {
"updateRequired": true,
"retriggerRequired": false,
"showConsentOnLaunch": true,
"reasons": ["FIRST_RUN", "NO_CACHED_CONFIG"]
}
}

Bu örneğin aynısı ayrıca [00-auth.response.json](./00-auth.response.json) dosyasında yer alır.


6. Retrigger / Karar Matrisi​

Sunucu, cihazdaki localState versiyonlarını remote versiyonlarla karşılaştırarak karar üretir. Retrigger, yalnızca onay zaten varken içerik/majör şema değişirse veya zaman interval'ı aşılır tetiklenir; uiVersion yalnız değişimi reprompt üretmez.

Cihaz durumuRemote durumuupdateRequiredretriggerRequiredshowConsentOnLaunchreasons
Hiç onay yok, cache boşherhangitruefalsetrueFIRST_RUN, NO_CACHED_CONFIG
İlk açılış, cache var ama versiyonlar eskiremote yenisitruefalsetrueFIRST_RUN, UI_UPDATED / CONTENT_UPDATED
Onay var, cihaz == remoteeşitfalsefalsefalseNO_CHANGE
Onay var, contentVersion/legalVersion arttıremote yenisitruetruetrueCONTENT_UPDATED / LEGAL_UPDATED
Onay var, schemaVersion major arttımajor bumptruetruetrueMAJOR_SCHEMA_CHANGE
Onay var, yalnız uiVersion arttıremote yenisitruefalsefalseUI_UPDATED
interval tanımlı ve lastShownAt aşıyor—falsetruetrueINTERVAL_RETRIGGER
Token süresi dolmuş, yeni AUTH—truefalse—TOKEN_EXPIRED

Retrigger tetikleyicileri (config behavior.retrigger üzerinden ayarlanır):

TetikleyiciConfig alanıEtkiReprompt üretir mi?
İçerik değişikliğionConfigChange + contentVersion/legalVersion bumpOnay ekranı yeniden sorulurEvet
Majör şema değişikliğionMajorChange + schemaVersion majorOnay ekranı yeniden sorulurEvet
Zaman aralığıinterval + lastShownAtInterval aşıldıysa periyodik repromptEvet
Görsel değişiklikuiVersion bumpYalnız tema/banner yenilenirHayır

Detayda bu tetikleyiciler config'in behavior.retrigger bloğunda tanımlanır (onConfigChange / onMajorChange / interval). Müşteri, reprompt davranışını bu flag'lerle ayarlar (örn. interval: "180d" → 180 günde bir tekrar sor).


7. Hata Kodları​

Hatalarda ortak gövde döner: { success:false, code, message, retryable, requestId }. message insan-okunur teşhis metnidir; UI'da gösterilmez (kullanıcıya gösterilecek metin config'in localization bloğundan gelir, ör. error_state).

codeHTTPretryableAçıklama / SDK müdahalesi
OK200—Başarılı.
INVALID_API_KEY401HayırapiKey geçersiz/bilinmiyor → kendi Console'unda anahtarı kontrol et.
SIGNATURE_MISMATCH401HayırHMAC imza doğrulanamadı (secret/anahtar tutarsızlık) → imza girdisi + secret kontrolü.
REPLAY_DETECTED401HayırNonce tekrar kullanıldı veya timestamp replay penceresi dışı → cihaz saati + nonce üretimi.
PACKAGE_MISMATCH403HayırapiKey bu packageName'e tanımlı değil → Console'da uygulama/anahtar eşleşmesi.
CONSENT_NOT_FOUND404HayırconsentId kaydı yok → consentId değeri doğrulanmalı.
VALIDATION_ERROR400HayırGövde şemayı karşılamıyor (zorunlu eksik/tip/enum hatası) → detail[] alan hatalarını düzelt.
CLOCK_DRIFT400EvetCihaz saati sunucudan kabul edilemez ölçüde sapmış → NTP ile ayarla.
RATE_LIMITED429EvetHız sınırı aşıldı → Retry-After (sn) kadar bekle, yeniden dene.
SERVER_ERROR500EvetSunucu iç hata → önbellek config kullanılır, arka planda yeniden denenebilir.

retryable semantiği: false → aynı istekle tekrar denemek işe yaramaz; farklı müdahale gerekir. true → daha sonra yeniden denenebilir.


8. Offline Davranışı (KRİTİK)​

Onay deneyimi sessizce bozulmamalı. Bağlantı yoksa bile kullanıcı onay akışını yaşar.

  1. AUTH, timeout (15 sn) veya hata ile başarısız olursa → SDK, son bilinen önbellek config'i + onay durumunu kullanmaya devam eder.
  2. Bağlantı gelince arka planda AUTH yeniden denenebilir; decision.updateRequired === true ise config yenileme tetiklenir.
  3. Hiç önbellek yoksa (ilk kurulum + çevrimdışı) → SDK'ya dahil edilen (bundled) varsayılan config ile onay akışı çalışır; kullanıcı boş ekranda bırakılmaz.
  4. Tüm çevrimdışı denemeler exponential backoff ile sınırlıdır; sonsuz döngü üretilmez.

9. Developer Notları​

  1. AUTH hafif kalmalıdır. Her açılışta yalnız versiyon + token + decision döner. Tam config, decision.updateRequired === true olduğunda 01 · GET /config ile çekilir — asla AUTH yanıtının içine gömülmez.
  2. Token = oturum kimliği. tokenExpiresIn penceresi boyunca hem config okuması (tüketmez) hem onay kaydı (tüketir) için geçerlidir. Pencere dolunca veya oturum kapanınca yeniden AUTH yapılır. Token, bağlı olduğu consentId'e bağlıdır; başka consentId ile kullanılamaz.
  3. Versiyon modeli üç seviyeli ve bağımsızdır. İçerik veya majör şema değişimi → reprompt; yalnız görsel değişimi → reprompt yok, sadece görsel yenileme.
  4. localState geri beslemedir. SDK bunu cihazda önbelleğe alır ve her AUTH'ında gönderir; ilk çalıştırmada null/boş bırakılır. Doğru retrigger kararı bu bloğun doluluğuna bağlıdır.
  5. consent haritasının anahtarları groupId'lerdir. Değerler yalnız granted/denied. essential grubu her zaman granted'tir (kilitli) → security_storage asla denied yapılmaz. GTM/etiketlere dağıtım (groupId → consentKeys) SDK tarafında yapılır (02 adımında).

Bu doküman size yardımcı oldu mu?

Değerlendirmeniz, dokümanı geliştirmemize yardımcı olur.

Değerlendirme yapmak için giriş yapmalısınız.

Destek soruları ve yorumlar

Bu dokümanla ilgili soru sorabilir veya deneyiminizi paylaşabilirsiniz.