---
title: 'Kapsamlar ve İzinler'
source: 'https://academia.sh/tr/kurslar/kimlik-ve-yetki/kapsamlar-ve-izinler'
course: 'Kimlik Doğrulama ve Yetkilendirme'
language: tr
updated: '2026-08-17T18:06:49+00:00'
license: 'CC BY-SA 4.0'
---

# Kapsamlar ve İzinler

Belirteç kapsamının sahibinin yetkisinden dar tutulması, kapsam ve izin katmanlarının kesişimiyle verilen karar, reddin nedenine göre ayrışan yanıtlar, erişim yüzeyinin ölçülmesi ve yenilemede daraltma kuralı.

Önceki dört ders kararı **kişiye** bağladı: kim hangi rolde, hangi özniteliklere sahip,
nesneyle nasıl bir ilişkisi var. Bu soruların yanıtı bir kişi için sabittir. Ancak isteği
yapan çoğu zaman kişinin kendisi değildir: kütüphanenin mobil uygulaması, bir rapor aracı,
kişinin yetkilendirdiği üçüncü taraf bir okuma listesi servisi.

Bu istemcilere kişinin bütün yetkisini vermek gereksizdir. Okuma listesi servisinin ödünç
kaydı silmeye ihtiyacı yoktur; rapor aracının üye adresini okumaya ihtiyacı yoktur.
**Kapsam (scope)**, bir belirtecin taşıdığı yetkinin, sahibinin yetkisinden **daha dar**
olmasını sağlayan mekanizmadır.

## İki Katmanlı Karar

Kapsam, önceki derslerdeki yetki modellerinin yerine geçmez; üstüne biner. Bir istek iki
soruyu birden geçmek zorundadır: **kişi bunu yapabilir mi** ve **bu istemciye bu yetki
verilmiş mi**. İkisi ayrı kaynaklardan gelir — birincisi kullanıcı yönetiminden, ikincisi
belirtecin verildiği andaki onaydan.

Karar bu yüzden bir kesişimdir. Kapsam yetkiyi genişletemez: bir belirteçte `ceza:yaz`
kapsamı bulunması, sahibinin ceza tahsil etme izni yoksa hiçbir şey ifade etmez. Tersi de
geçerlidir: yetkili bir görevlinin belirteci, kapsamı dışındaki uç noktaya erişemez.

Aşağıdaki hesap bu iki katmanı bir eşleme tablosu üzerinde çalıştırır.

```bash
cat > kapsam.mjs <<'EOF'
// kapsam.mjs — belirtec kapsamlarinin uc noktalara eslenmesi ve iki katmanli karar

// 1. Uc nokta -> gereken kapsam eslemesi. Sozlesmenin parcasidir.
const UC_NOKTALAR = [
  { yontem: "GET",    yol: "/oduncler",            kapsam: "odunc:oku" },
  { yontem: "POST",   yol: "/oduncler",            kapsam: "odunc:yaz" },
  { yontem: "DELETE", yol: "/oduncler/{id}",       kapsam: "odunc:yaz" },
  { yontem: "GET",    yol: "/uyeler/{id}",         kapsam: "uye:oku" },
  { yontem: "PATCH",  yol: "/uyeler/{id}",         kapsam: "uye:yaz" },
  { yontem: "GET",    yol: "/uyeler/{id}/cezalar", kapsam: "ceza:oku" },
  { yontem: "POST",   yol: "/cezalar/{id}/tahsil", kapsam: "ceza:yaz" },
  { yontem: "GET",    yol: "/raporlar/gecikme",    kapsam: "rapor:oku" },
];

// 2. Ozne izinleri (RBAC dersinden): kisinin yapabildikleri.
const IZINLER = {
  "U-1001": new Set(["odunc:oku", "odunc:yaz", "uye:oku", "ceza:oku"]),
  "P-2001": new Set(["odunc:oku", "odunc:yaz", "uye:oku", "uye:yaz", "ceza:oku", "ceza:yaz"]),
  "Y-3001": new Set(["odunc:oku", "odunc:yaz", "uye:oku", "uye:yaz", "ceza:oku", "ceza:yaz", "rapor:oku"]),
};

// 3. Belirtecler: istemciye verilen kapsam kumesi. Kisinin izinleriyle ayni sey degildir.
const BELIRTECLER = [
  { ad: "mobil-uygulama", ozne: "U-1001", kapsamlar: ["odunc:oku", "odunc:yaz", "uye:oku"] },
  { ad: "okuma-listesi",  ozne: "U-1001", kapsamlar: ["odunc:oku"] },
  { ad: "rapor-araci",    ozne: "P-2001", kapsamlar: ["rapor:oku", "odunc:oku"] },
  { ad: "banko-uygulamasi", ozne: "Y-3001", kapsamlar: ["odunc:oku", "odunc:yaz", "uye:yaz", "ceza:yaz"] },
];

// 4. Karar: iki katman da gecmeli. Kapsam istemcinin yetkisini, izin kisinin yetkisini sinirlar.
function karar(belirtec, uc) {
  const kapsamVar = belirtec.kapsamlar.includes(uc.kapsam);
  const izinVar = IZINLER[belirtec.ozne].has(uc.kapsam);
  if (!kapsamVar && !izinVar) return "red: kapsam ve izin yok";
  if (!kapsamVar) return "red: belirtecin kapsami yok";
  if (!izinVar) return "red: oznenin izni yok";
  return "izin";
}

const dolgu = (s, n) => String(s).padEnd(n);
console.log("belirtec           uc nokta                          sonuc");
for (const b of BELIRTECLER) {
  for (const uc of UC_NOKTALAR) {
    const s = karar(b, uc);
    if (s === "izin") continue;                       // yalniz reddedilenleri goster
    if (!IZINLER[b.ozne].has(uc.kapsam) && !b.kapsamlar.includes(uc.kapsam)) continue;
    console.log(`${dolgu(b.ad, 18)} ${dolgu(uc.yontem + " " + uc.yol, 33)} ${s}`);
  }
}

// 5. Kapsamin erisim yuzeyi: her belirtec kac uc noktaya ulasabiliyor?
console.log("\nbelirtec           kapsam  izinli uc nokta  yuzey");
for (const b of BELIRTECLER) {
  const izinli = UC_NOKTALAR.filter((uc) => karar(b, uc) === "izin");
  const yuzde = ((100 * izinli.length) / UC_NOKTALAR.length).toFixed(0);
  console.log(`${dolgu(b.ad, 18)} ${dolgu(b.kapsamlar.length, 7)} ${dolgu(izinli.length + " / " + UC_NOKTALAR.length, 16)} %${yuzde}`);
}

// 6. Kapsam taneciginin etkisi: kaba kapsam ile ince kapsamin yuzeyi.
const KABA = ["odunc:*", "uye:*"];
const kabaEsler = (uc) => KABA.some((k) => uc.kapsam.startsWith(k.slice(0, -1)));
const kabaYuzey = UC_NOKTALAR.filter(kabaEsler).length;
const inceYuzey = UC_NOKTALAR.filter((uc) => ["odunc:oku", "uye:oku"].includes(uc.kapsam)).length;
console.log(`\nkaba kapsam ${JSON.stringify(KABA)} -> ${kabaYuzey} / ${UC_NOKTALAR.length} uc nokta`);
console.log(`ince kapsam ["odunc:oku","uye:oku"] -> ${inceYuzey} / ${UC_NOKTALAR.length} uc nokta`);
console.log(`okuma isteyen bir istemciye kaba kapsam verilirse fazladan ${kabaYuzey - inceYuzey} uc nokta acilir.`);

// 7. Yenilemede daraltma: istemci daha az kapsam isteyebilir, daha cogunu isteyemez.
function yenile(belirtec, istenen) {
  const disarida = istenen.filter((k) => !belirtec.kapsamlar.includes(k));
  return disarida.length
    ? { sonuc: "red", neden: "istenen kapsam ilk belirtecin disinda: " + disarida.join(", ") }
    : { sonuc: "kabul", kapsamlar: istenen };
}
const mobil = BELIRTECLER[0];
console.log("\nyenileme denemeleri (ilk kapsam: " + JSON.stringify(mobil.kapsamlar) + ")");
for (const istenen of [["odunc:oku"], ["odunc:oku", "uye:oku"], ["odunc:oku", "ceza:yaz"]]) {
  const y = yenile(mobil, istenen);
  console.log(`  ${dolgu(JSON.stringify(istenen), 34)} ${y.sonuc}${y.neden ? " — " + y.neden : ""}`);
}
EOF
node kapsam.mjs
```

```text
belirtec           uc nokta                          sonuc
mobil-uygulama     GET /uyeler/{id}/cezalar          red: belirtecin kapsami yok
okuma-listesi      POST /oduncler                    red: belirtecin kapsami yok
okuma-listesi      DELETE /oduncler/{id}             red: belirtecin kapsami yok
okuma-listesi      GET /uyeler/{id}                  red: belirtecin kapsami yok
okuma-listesi      GET /uyeler/{id}/cezalar          red: belirtecin kapsami yok
rapor-araci        POST /oduncler                    red: belirtecin kapsami yok
rapor-araci        DELETE /oduncler/{id}             red: belirtecin kapsami yok
rapor-araci        GET /uyeler/{id}                  red: belirtecin kapsami yok
rapor-araci        PATCH /uyeler/{id}                red: belirtecin kapsami yok
rapor-araci        GET /uyeler/{id}/cezalar          red: belirtecin kapsami yok
rapor-araci        POST /cezalar/{id}/tahsil         red: belirtecin kapsami yok
rapor-araci        GET /raporlar/gecikme             red: oznenin izni yok
banko-uygulamasi   GET /uyeler/{id}                  red: belirtecin kapsami yok
banko-uygulamasi   GET /uyeler/{id}/cezalar          red: belirtecin kapsami yok
banko-uygulamasi   GET /raporlar/gecikme             red: belirtecin kapsami yok

belirtec           kapsam  izinli uc nokta  yuzey
mobil-uygulama     3       4 / 8            %50
okuma-listesi      1       1 / 8            %13
rapor-araci        2       1 / 8            %13
banko-uygulamasi   4       5 / 8            %63

kaba kapsam ["odunc:*","uye:*"] -> 5 / 8 uc nokta
ince kapsam ["odunc:oku","uye:oku"] -> 2 / 8 uc nokta
okuma isteyen bir istemciye kaba kapsam verilirse fazladan 3 uc nokta acilir.

yenileme denemeleri (ilk kapsam: ["odunc:oku","odunc:yaz","uye:oku"])
  ["odunc:oku"]                      kabul
  ["odunc:oku","uye:oku"]            kabul
  ["odunc:oku","ceza:yaz"]           red — istenen kapsam ilk belirtecin disinda: ceza:yaz
```

## Reddin Nedeni Ayırt Edilebilir Olmalı

Çıktının ilk bölümü reddedilen istekleri nedenleriyle listeliyor. İki neden birbirinden
ayrıdır ve bu ayrım geliştiriciye farklı şey söyler.

"Belirtecin kapsamı yok" onarılabilir bir durumdur: istemci kullanıcıdan ek onay isteyip
daha geniş kapsamlı bir belirteç alabilir. "Öznenin izni yok" ise onarılamaz; hiçbir onay
akışı görevliye rapor okuma izni veremez, çünkü o izin kullanıcı yönetiminde tanımlıdır.
Rapor aracı satırı bunun örneğidir: belirteçte `rapor:oku` kapsamı vardır ama öznenin izni
yoktur, dolayısıyla istek reddedilir.

İstemciye dönen yanıt bu ayrımı taşımalıdır. Yetersiz kapsam için standart, hangi kapsamın
gerektiğini bildiren bir yanıttır; yetersiz izin için ise ek bilgi verilmez — kullanıcının
neye yetkili olmadığını ayrıntılandırmak, yetki haritasını dışarıya sızdırır.

## Kapsam Bir Erişim Yüzeyidir

İkinci bölüm her belirtecin kaç uç noktaya ulaşabildiğini sayıyor. Bu sayı, belirteç
sızdığında ne kadar zarar verilebileceğinin doğrudan ölçüsüdür: okuma listesi servisinin
belirteci sekiz uç noktanın birine, banko uygulamasının belirteci beşine erişir.

Yüzeyin ölçülebilir olması bir tasarım aracıdır. Bir istemcinin istediği kapsam kümesi
onaylanmadan önce sorulacak soru şudur: bu kümenin açtığı uç nokta sayısı, istemcinin
gerçekten yaptığı işle orantılı mı? Okuma listesi servisi yalnız ödünç geçmişini okuyorsa
`odunc:oku` yeterlidir; `odunc:yaz` istemesi, yüzeyi üç katına çıkarır ve gerekçesi
yoktur.

## Tanecik Boyutu Bir Karardır

Üçüncü bölüm kaba ve ince kapsamı karşılaştırıyor. Kaynak başına tek bir kapsam
tanımlamak — `odunc:*` gibi — kapsam listesini kısaltır ama okuma isteyen bir istemciye
yazma yetkisini de verir; modelde bu, fazladan üç uç nokta demektir.

Ters uçta her uç nokta için ayrı kapsam tanımlamak da işe yaramaz: kapsam listesi
büyüdükçe onay ekranı okunamaz hâle gelir ve kullanıcı listeyi okumadan onaylar. İşe
yarayan tanecik, **kaynak ve eylem** ikilisidir: `odunc:oku`, `odunc:yaz`. Bu düzeyde
kapsam sayısı kaynak sayısının iki katıdır ve her kapsamın karşılığı bir cümleyle
anlatılabilir.

Kapsam adının kendisi de sözleşmenin parçasıdır. Uç nokta değiştiğinde kapsam adı sabit
kalır; kapsam adı değiştiğinde bütün istemcilerin yeniden onay alması gerekir. Bu, API
Sürümleme dersindeki kırıcı değişiklik kuralının yetkilendirme tarafındaki karşılığıdır.

## Yenilemede Daraltma Vardır, Genişletme Yoktur

Son bölüm yenileme davranışını gösteriyor. Bir istemci elindeki belirteci yenilerken daha
**dar** bir kapsam kümesi isteyebilir; bu, uzun ömürlü bir oturumda geçici olarak daha az
yetkiyle çalışmayı mümkün kılar. Daha **geniş** bir küme isteyemez: genişletme, yeni bir
onay akışı gerektirir.

Kural tek cümleyle yazılır: yenilenen belirtecin kapsamı, ilk belirtecin kapsamının alt
kümesi olmalıdır. Bu kuralın uygulanmaması, yenileme uç noktasını sessiz bir yetki
yükseltme yoluna çevirir — çünkü yenileme, kullanıcı onayı olmadan çalışan bir akıştır.

## Özet

- Kapsam, belirtecin yetkisini sahibinin yetkisinden daha dar tutar; karar iki katmanın
  kesişimidir ve kapsam hiçbir zaman yetkiyi genişletmez.
- Yetersiz kapsam ile yetersiz izin farklı yanıtlar üretir: birincisi hangi kapsamın
  gerektiğini bildirir, ikincisi ayrıntı vermez.
- Bir belirtecin eriştiği uç nokta sayısı, sızma durumundaki zararın ölçüsüdür; modelde
  belirteçlerin yüzeyi yüzde on üç ile yüzde altmış üç arasında değişiyor.
- Tanecik kaynak–eylem düzeyinde tutulur: kaba kapsam okuma isteyen istemciye üç fazladan
  uç nokta açar, aşırı ince kapsam onay ekranını okunamaz yapar.
- Yenilemede kapsam yalnız daraltılabilir; genişletme yeni onay gerektirir, aksi hâlde
  yenileme sessiz bir yetki yükseltme yoluna dönüşür.

## Sonraki Adım

Buraya kadarki bütün kararlar tek bir kütüphanenin içinde verildi: bir üye, bir görevli,
bir şube. Aynı sunucu birden çok kütüphaneye hizmet verdiğinde araya yeni bir sınır girer
ve bu sınır rol ya da kapsamla değil **veriyle** çizilir: bir kütüphanenin görevlisi, kendi
kurumunun kayıtlarını görebilmeli, komşu kurumunkileri hiçbir koşulda görememelidir.
Sonraki ders bu yalıtımı ele alır ve sınırın sorgunun kendisine nasıl taşındığını gösterir.
