WordPress

WordPress REST API Nedir? Kullanım ve Güvenlik

WordPress REST API nedir, ne işe yarar?

Gece gelen bir destek biletinde müşterinin ilk cümlesi genellikle şudur: “REST API açık görünüyor, site saldırıya mı uğradı?” Çoğu zaman cevap hayırdır. WordPress’in herkese açık yazıları JSON biçiminde sunması beklenen bir davranıştır; asıl mesele hangi verilerin açıldığı ve değişiklik yapabilen uç noktaların nasıl korunduğudur.

WordPress REST API, yönetim panelini açmadan site verilerine HTTP istekleri üzerinden erişmenizi sağlayan arayüzdür. Bir yazıyı okuyabilir, yeni içerik oluşturabilir veya bir ürünün bilgisini başka bir uygulamaya aktarabilirsiniz.

Şöyle anlatayım: WordPress paneli, veritabanı tablolarını ve PHP kodunu doğrudan kullanan klasik arayüzdür. REST API ise bu verilerin kontrollü bir kapıdan dışarı sunulmasıdır. Kapı vardır; fakat her ziyaretçiye her odayı açmak zorunda değildir.

Standart REST API adresi genellikle şu biçimdedir:

https://example.com/wp-json/wp/v2/posts

Bu adres sitenin yazılarını döndürür. /wp/v2/pages sayfaları, /wp/v2/media medya dosyalarını, WooCommerce kuruluysa uygun kimlik doğrulamayla /wc/v3/products ürünleri temsil eder.

Bir destek biletinde bu adresi ilk kez gören müşterinin sitenin saldırıya uğradığını düşündüğünü hatırlıyorum. Yazıların JSON olarak listelenmesi çoğu WordPress kurulumunda normaldir. Şüphelenmem gereken yer, müşteri adresleri veya ürün maliyetleri gibi özel verilerin yetkisiz yanıtta görünmesidir.

İstek ve yanıt mantığı

REST API kaynaklarla çalışır. Bir yazı, sayfa, kullanıcı veya medya dosyası kaynak olarak düşünülebilir. HTTP metodu da yapmak istediğiniz işlemi anlatır:

HTTP metoduTipik kullanımKimlik doğrulama
GETVeri okuma ve listelemeHerkese açık içerikte çoğunlukla gerekmez
POSTYeni kaynak oluşturmaGerekir
PUT veya PATCHMevcut kaynağı güncellemeGerekir
DELETEKaynak silmeGerekir

Örneğin son yazıları görmek için:

curl -s 'https://example.com/wp-json/wp/v2/posts?per_page=3&_fields=id,date,link,title'

Burada per_page=3 üç kayıt ister. _fields ise gereksiz alanları yanıtın dışında bırakır. İstemciye daha az veri gittiği için bu seçenek mobil uygulamalarda ve sık çalışan entegrasyonlarda işime yarar.

Liste yanıtının yanında WordPress toplam kayıt sayısını HTTP başlıklarında verir. X-WP-Total toplam kayıtları, X-WP-TotalPages toplam sayfa sayısını gösterir. Büyük bir içerik arşivini aktarırken yalnızca JSON gövdesine bakmam; bu iki başlığı da kontrol ederim.

Tek bir yazıyı kimliğiyle çağırmak için:

curl -s 'https://example.com/wp-json/wp/v2/posts/123'

Buradaki 123 yazının kimliğidir. Kimlik bulunamazsa veya kaynak yayınlanmamışsa 404 benzeri bir REST hatası alabilirsiniz. REST API adresinin çalışmaması her zaman hosting arızası değildir; kalıcı bağlantı kuralları, güvenlik eklentisi veya sunucu katmanındaki bir kural da isteği etkileyebilir.

Hangi projelerde kullanılır?

WordPress REST API, içeriği üreten sistem ile içeriği gösteren arayüzü birbirinden ayırmanıza izin verir. Bu mimariye headless WordPress denir. API kullanmak için sitenin tamamen headless olması gerekmez.

  • Mobil uygulamaya yazı, kategori ve medya bilgisi sağlamak.
  • React, Vue veya başka bir JavaScript arayüzünde WordPress içeriği göstermek.
  • Harici CRM, ERP veya stok sistemiyle içerik ve ürün verisi eşitlemek.
  • İçerik editörlerinin tekrar eden işlemlerini otomatikleştirmek.
  • Birden fazla WordPress sitesindeki duyuruları ortak bir arayüzde toplamak.
  • WooCommerce ürünlerini yetkili bir iç uygulamada listelemek veya güncellemek.

Bir sitenin SEO ve ölçüm tarafını API ile beslemek mümkündür. API üzerinden veri çekmek ise Google’ın o veriyi otomatik olarak arama sonuçlarında kullanacağı anlamına gelmez. Teknik entegrasyon ile arama motoru davranışını birbirine karıştırmamak gerekir. Ölçüm zincirini kontrol etmek isteyenler için GA4 Kurulumu: Web Sitenizi Adım Adım İzleyin yazısında farklı bir doğrulama yöntemi anlatılıyor.

WooCommerce tarafında ürün ve sipariş uç noktaları daha hassastır. Bir ürünün herkese açık adı ve fiyatı ile müşterinin adres bilgisi aynı güvenlik sınıfında değildir. Entegrasyonu tasarlarken veri alanlarını tek tek belirlemek, tüm nesneyi olduğu gibi dışarı vermekten daha güvenlidir.

WordPress REST API ile veri okuma

Filtreleme, arama ve sayfalama

REST API sorgu parametreleriyle yanıtı daraltabilirsiniz. Belirli bir arama terimiyle ve kategori kimliğiyle yazı istemek için:

curl -s 'https://example.com/wp-json/wp/v2/posts?search=linux&categories=7&per_page=10&page=2'

Bu istek Linux kelimesini içeren, 7 numaralı kategoriye bağlı yazıların ikinci sayfasını ister. page değeri mevcut sayfa sayısını aşarsa API hata yanıtı döndürebilir; otomasyon kodu bu durumu beklemelidir.

Alan seçimi için _fields kullanmak yalnızca performans ayarı değildir. İstemcinin görmesine gerek olmayan alanların taşınmasını da azaltır:

curl -s 'https://example.com/wp-json/wp/v2/posts?per_page=5&_fields=id,slug,title.rendered,excerpt.rendered'

HTML içeren alanlarda title.rendered veya excerpt.rendered biçimini görürsünüz. Bu alanları başka bir sayfada gösterirken ham biçimi güvenilir kabul etmeyin; kullandığınız arayüz katmanında uygun kaçış ve temizleme işlemini uygulayın.

İçerik durumları ve context parametresi

Herkese açık istekler çoğunlukla view bağlamında çalışır. Yetkili kullanıcılar için edit bağlamı daha fazla alan döndürebilir. Taslak, özel alan veya düzenleme bilgileri bu bağlamda ortaya çıkabilir.

context=edit kullanmak tek başına yetki sağlamaz. Sunucu, isteği yapan kullanıcının ilgili kaynağı düzenleme iznini ayrıca denetler. Bu ayrımı bilmeden gizli alanları istemci tarafında saklamaya çalışmak sık rastladığım hatalardan biridir.

Kimlik doğrulama yöntemleri

Çerez ve nonce ile oturum tabanlı kullanım

WordPress yönetim panelinde oturum açmış bir kullanıcı, tarayıcı içindeki JavaScript koduyla REST API isteği gönderebilir. Bu senaryoda WordPress oturum çerezine ek olarak wp_rest nonce değeri kullanılır. Nonce, isteğin panel oturumu içindeki beklenen kaynaktan geldiğini kontrol etmeye yardımcı olur.

Bu yöntem site içindeki yönetim ekranlarında kullanışlıdır. Harici bir sunucunun uzun süreli entegrasyonu için tarayıcı oturum çerezini kopyalamak doğru yaklaşım değildir.

Application Passwords

WordPress’in yerleşik Application Passwords özelliği, bir kullanıcı hesabı için ayrı bir uygulama parolası üretir. Bu parola temel kimlik doğrulama başlığıyla HTTPS üzerinden gönderilebilir:

curl --user 'api-user:uygulama-parolasi' \
  -H 'Content-Type: application/json' \
  'https://example.com/wp-json/wp/v2/users/me'

Yanıt, kimlik doğrulamasının hangi kullanıcıyla yapıldığını gösterir. Uygulama parolasını normal kullanıcı parolası gibi paylaşmayın, kod deposuna yazmayın ve gerekmiyorsa yetkili bir yönetici hesabına bağlamayın.

Bir yazı oluşturma örneği şöyle olabilir:

curl --user 'api-user:uygulama-parolasi' \
  -X POST 'https://example.com/wp-json/wp/v2/posts' \
  -H 'Content-Type: application/json' \
  -d '{"title":"API ile oluşturulan taslak","content":"İçerik burada","status":"draft"}'

Bu istek taslak bir yazı oluşturur. Komut canlı sitede çalıştırılmadan önce hedef site, kullanıcı ve status değeri kontrol edilmelidir. Yanlış endpoint’e gönderilen POST isteği geri alınabilir bir önizleme değildir.

JWT ve OAuth ne zaman düşünülür?

JWT veya OAuth, özel mobil uygulamalarda ya da ayrı servis mimarilerinde karşınıza çıkabilir. Bunlar WordPress çekirdeğinin her kurulumda aynı şekilde sunduğu tek bir standart çözüm değildir; çoğunlukla eklenti, reverse proxy veya ayrı bir kimlik servisi gerektirir.

Bir eklentinin popüler olması güvenli yapılandırıldığı anlamına gelmez. Token süresi, yenileme yöntemi, iptal mekanizması, TLS kullanımı ve hata loglarında token sızıp sızmadığı incelenmelidir. Ben küçük entegrasyonlarda önce yerleşik Application Passwords ile en az yetkili kullanıcıyı kurarım. İhtiyaç oluşmadan JWT katmanı eklemem.

Özel REST endpoint yazarken güvenlik

Bir eklenti veya tema ile özel endpoint ekleyebilirsiniz:

register_rest_route( 'magaza/v1', '/stok/(?P<sku>[A-Za-z0-9_-]+)', array(
    'methods'             => WP_REST_Server::READABLE,
    'callback'            => 'magaza_stok_getir',
    'permission_callback' => 'magaza_stok_izni',
) );

Burada namespace sürümlendirilmiştir ve SKU için bir desen tanımlanmıştır. Asıl güvenlik permission_callback içinde yer alır. Bu alanı boş bırakmak veya eski örneklerde görülen __return_true yaklaşımını düşünmeden kullanmak risklidir.

İzin kontrolünü kullanıcı yeteneğine bağlayabilirsiniz:

function magaza_stok_izni( WP_REST_Request $request ) {
    return current_user_can( 'manage_woocommerce' );
}

Ne yaptık? İsteği yapan kullanıcının WooCommerce stoklarını yönetme yeteneği yoksa callback çalıştırılmıyor. Capability seçimi sitenin rol yapısına uygun olmalı; her işlem için doğrudan manage_options vermek en az yetki ilkesini bozar.

Girdi doğrulama ve çıktı temizleme

REST API’den gelen veriyi güvenilir kabul etmeyin. Parametre tipi, izin verilen değerler, uzunluk ve iş bağlamı kontrol edilmelidir. Ürün miktarı beklenen bir tamsayıysa metin olarak gelen değeri sessizce kabul etmek yerine doğrulayın. Metin alanlarında uygun WordPress temizleme fonksiyonlarını kullanın.

Yanıtı hazırlarken veritabanından gelen her alanı olduğu gibi döndürmek de doğru değildir. E-posta, adres, iç not, müşteri kimliği veya özel meta alanları gerekmiyorsa yanıt dışında bırakılmalıdır. register_rest_field ile eklenen alanlarda özellikle dikkatli olun; bir alanı göstermek kolay, yanlışlıkla herkese açıldığını sonradan fark etmek pahalıdır.

Nonce, CORS ve HTTPS

Nonce, kimlik doğrulamanın yerine geçmez. CORS da yetki sistemi değildir; yalnızca hangi tarayıcı kaynaklarının yanıtı okuyabileceğini etkiler. Sunucuya gelen isteğin kimliğini ve kullanıcının yetkisini ayrıca kontrol etmek gerekir.

Kimlik bilgileri, Application Passwords ve içerik güncelleme istekleri yalnızca HTTPS üzerinden taşınmalıdır. HTTP yönlendirmesinin varlığına güvenerek parolayı HTTP URL’sine göndermeyin; istemci doğrudan doğru HTTPS adresini kullanmalıdır.

REST API’yi kapatmak mı, korumak mı?

Bir sitenin REST API çıktısında herkese açık yazıların bulunması tek başına güvenlik açığı değildir. API’yi tümden kapatmak blok editörünü ve bazı modern eklentileri bozabilir. Ben önce hangi endpoint’in gerçekten sorun oluşturduğunu belirlemeyi tercih ederim.

Kullanıcı adlarını REST API üzerinden sorgulamayı sınırlamak, hassas özel endpoint’leri yetki kontrolüne almak ve gereksiz eklentileri kaldırmak çoğu zaman tüm API’yi kapatmaktan daha sağlıklıdır. Güvenlik eklentisinin genel kuralının beklenen mobil uygulamayı veya editör bağlantısını kesmediğini de test edin.

WordPress Site Sağlığı Raporu Nasıl Okunur? yazısındaki kontroller burada da işe yarar. REST API ile ilgili hata gördüğünüzde yalnızca güvenlik eklentisini suçlamayın; PHP sürümü, kalıcı bağlantılar, REST testi, loopback istekleri ve sunucu logları birlikte incelenmelidir.

Özel endpoint’ler yönetici işlemleri yapıyorsa denetim izi de bırakın. Kim, hangi kaydı, ne zaman ve hangi istemci üzerinden değiştirdi soruları daha sonra cevaplanabilmelidir. Loglama ve Denetim İzi Mimarisi: Yönetici İşlemlerini KVKK/GDPR Uyumlu Kaydetmek başlığında bu kayıtların kişisel veri tarafı ayrıca ele alınıyor.

Performans ve operasyon tarafı

Bir istemci her sayfa yüklemesinde binlerce yazıyı çekerse API doğru çalışsa bile mimari yanlış kurulmuş olur. Sayfalama, _fields, uygun önbellekleme ve değişmeyen veriler için ETag veya Last-Modified başlıkları kullanılabilir.

Cache katmanı kullanırken yetkili ve yetkisiz yanıtları birbirine karıştırmayın. context=edit ile alınan veya kullanıcıya özel veriler herkese açık önbellekte tutulmamalıdır. CDN üzerinde Authorization başlığı taşıyan isteklerin nasıl işlendiğini ayrıca kontrol edin.

Rate limit yalnızca saldırı anında düşünülmemeli. Hatalı yazılmış bir senkronizasyon görevi aynı endpoint’e saniyede yüzlerce istek göndererek PHP worker’larını tüketebilir. Hosting tarafında bunu access log, uygulama logu ve CPU/RAM gözlemiyle birlikte değerlendiririm. “API yavaş” biletinde önce istek sayısını, yanıt boyutunu ve sorgu parametrelerini ölçerim; sunucuyu büyütmek sonraki adımdır.

İzleme eklerken parola veya token değerlerini loglamayın. Başarısız isteklerde endpoint, HTTP kodu ve gerekiyorsa kullanıcı kimliği çoğu teşhis için yeterlidir. Hassas veriyi saklamadan da yeterli bir denetim izi kurulabilir.

Benim kontrol sıram

Yeni bir WordPress REST API entegrasyonunu canlıya almadan önce şu listeyi kullanıyorum:

  1. Endpoint’in namespace ve sürümü belirli mi?
  2. GET ile açılan veriler gerçekten herkese açık mı?
  3. POST, PATCH ve DELETE isteklerinde yetenek kontrolü var mı?
  4. İzin kontrolü başarısız olduğunda 401 veya 403 yanıtı doğru dönüyor mu?
  5. Girdi doğrulama, tip kontrolü ve çıktı temizleme yapılıyor mu?
  6. Yanıtta parola, token, müşteri adresi veya gereksiz özel alan kalıyor mu?
  7. HTTPS, CORS, rate limit ve cache davranışı test edildi mi?
  8. Bir hata durumunda loglarda yeterli ama ölçülü bilgi bulunuyor mu?
  9. Geri dönüş planı ve veritabanı yedeği hazır mı?

Değişiklikten önce wp db export almadan WordPress güncellemesi yapmadığım gibi, canlı entegrasyonda da önce staging testini tamamlarım. API çağrısını staging’de denemek kolaydır; yanlışlıkla gerçek müşteriye e-posta gönderen veya canlı ürünü güncelleyen otomasyonu geri almak o kadar kolay değildir.

Bir keresinde güvenlik eklentisi nedeniyle blok editörünün REST isteği 403 dönüyordu. Panel açılıyor, yazı kaydetme işlemi ise sessizce başarısız oluyordu. curl -i ile yanıt başlıklarını ve web sunucusu logunu birlikte kontrol ettiğimde sorunun WordPress çekirdeğinde değil, güvenlik eklentisinin genel REST kuralında olduğunu gördüm. Kuralı tüm API’yi kapatmadan daralttık ve staging’de yazı oluşturma, medya yükleme ve yetkisiz istek testlerini tekrarladık. Benim için ders basitti: önce hangi isteğin, hangi katmanda reddedildiğini bulun.

Sık Sorulan Sorular

WordPress REST API herkese açık mıdır?

Herkese açık yazı ve sayfa gibi kaynakların bazı alanları çoğu kurulumda kimlik doğrulama olmadan okunabilir. İçerik oluşturma, güncelleme, silme ve özel veriler için yetkilendirme gerekir; sitenizdeki eklentiler bu davranışı değiştirebilir.

WordPress REST API kapatılmalı mı?

Genellikle tüm API’yi kapatmak yerine hassas endpoint’leri ve kullanıcı bilgisi sızıntılarını sınırlamak daha doğru olur. Kapatma işlemi blok editörü, mobil uygulamalar veya bazı eklentilerle uyumsuzluk oluşturabilir.

REST API kullanmak için eklenti gerekir mi?

WordPress çekirdeği yazılar, sayfalar, medya ve kullanıcılar gibi birçok kaynak için yerleşik endpoint sunar. JWT gibi özel kimlik doğrulama yöntemleri veya özel iş akışları için eklenti ya da kendi geliştirdiğiniz kod gerekebilir.

REST API siteyi yavaşlatır mı?

API’nin kendisi otomatik olarak yavaşlık oluşturmaz; gereğinden fazla kayıt çekmek, ağır meta sorguları ve kontrolsüz otomasyon yük oluşturabilir. Sayfalama, _fields, önbellekleme ve rate limit kullanarak bu yükü ölçülebilir biçimde azaltabilirsiniz.