web geliştirme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
web geliştirme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

21 Kasım 2025 Cuma

Passkeys (FIDO2/WebAuthn) ile Şifresiz Kimlik Doğrulama: Adım Adım Uygulama Rehberi

Passkey nedir ve neden şimdi?

Parola yorgunluğu, kimlik avı ve bot saldırıları modern uygulamaların en büyük tehditlerinden. Passkey, FIDO2 ve WebAuthn standartlarına dayanan, parolasız ve kimlik avına dirençli bir doğrulama yaklaşımıdır. Kullanıcı, cihazındaki biyometri (parmak izi, Face ID) veya PIN ile giriş yapar; tarayıcı, cihazda üretilen özel anahtarı kullanır ve sunucuya sadece genel anahtar gider. Böylece veri ihlallerinde çalınacak parola kalmaz.

Mimariyi bir bakışta anlayın

WebAuthn istemci tarafı (tarayıcı ve platform autentikatörü) ile sunucu arasında çalışır. Kayıtta, sunucu bir “challenge” üretir; tarayıcı bu challenge’ı cihazın güvenli çipinde üretilen özel anahtar ile imzalar ve sunucuya genel anahtar + imza döner. Girişte de benzer şekilde geçici bir challenge imzalanır. Sunucu, daha önce sakladığı genel anahtar ile imzayı doğrular ve kullanıcıyı oturum açmış sayar.

Önkoşullar ve planlama

1) Alan adınız için HTTPS zorunludur. 2) Sunucu tarafında WebAuthn doğrulama yapabilecek bir kütüphane seçin (örn. dilinize uygun FIDO2/WebAuthn paketleri). 3) Kullanıcı akışını planlayın: önce passkey kaydı, ardından giriş. 4) Çoklu cihaz senaryosunu düşünün: senkronize passkey (Apple/Google ekosistemleri) ve güvenlik anahtarlarını (YubiKey vb.) desteklemek isteyebilirsiniz.

Kayıt (Registration) akışı

Adım 1: Sunucu, kullanıcı için bir kayıt challenge’ı ve RP (Relying Party) bilgilerini üretir. Adım 2: Tarayıcıda WebAuthn API’sini çağırarak cihazın bir anahtar çifti oluşturmasını istersiniz. Adım 3: Kullanıcı biyometri veya cihaz PIN’i ile onay verir. Adım 4: Tarayıcı, oluşturulan genel anahtarı, attestation ve ilgili meta verileri sunucuya gönderir. Adım 5: Sunucu, gelen veriyi doğrular; geçerli ise kullanıcı hesabına bu genel anahtarı bağlar. Bu aşamadan sonra kullanıcı, parolasız giriş yapabilecek duruma gelir.

Giriş (Authentication) akışı

Adım 1: Sunucu, giriş yapmak isteyen kullanıcı için bir challenge üretir ve tarayıcıya yollar. Adım 2: Tarayıcı, cihazda saklı özel anahtarı kullanarak challenge’ı imzalar; kullanıcı yine biyometri veya PIN ile onay verir. Adım 3: İmzalı veri sunucuya döner. Adım 4: Sunucu, ilgili genel anahtar ile imzayı doğrular ve başarılıysa oturumu başlatır. Tüm süreçte parola veya tek seferlik SMS kodu gerekmez.

Sunucu tarafı doğrulama ipuçları

Doğrulamada RP ID, origin ve challenge eşleşmelerine dikkat edin. Signature counter (sign count) değerini izleyerek olası anahtar klonlama şüphesini tespit edin. Mümkünse attestation doğrulamasını aktif edin ve yalnızca güvenilir üreticilerin autentikatörlerine izin verin. Kullanıcı başına birden çok passkey kaydını desteklemek, hesap kurtarma ve cihaz değişimi için hayat kurtarır.

Kullanıcı deneyimi: Mikro kılavuz

Kullanıcıları “Parolasız giriş” kavramına kısa bir açıklama ile hazırlayın. Kayıtta hangi yöntemlerin desteklendiğini (cihazın dahili biyometrisi, harici güvenlik anahtarı) net ifade edin. Giriş ekranında “Passkey ile devam et” butonu görünür olmalı; alternatif olarak e-posta ile büyülü bağlantı (magic link) veya yedek kodlar ikinci seçenek olarak sunulabilir. Cihaz desteklemiyorsa anlaşılır hata mesajları verin ve geçici olarak SMS/OTP gibi yöntemlere yönlendirin.

Güvenlik en iyi uygulamalar

- HTTPS her ortamda zorunlu. - CSRF ve oturum sabitleme saldırılarına karşı koruma sağlayın. - Rate limiting ve IP itibar kontrolleri ekleyin. - Kademeli yayına geçin: önce beta kullanıcıları ile test, sonra genelleme. - Attestation politikasını, regülasyon gerekliliklerine (ör. finans, sağlık) uyacak şekilde ayarlayın.

Uyumluluk ve tarayıcı desteği

Modern Chromium, Safari ve Firefox tarayıcıları WebAuthn’ı destekliyor. Mobilde iOS ve Android tarafında platform autentikatörleri olgunlaştı. Eski cihazlarda destek kısıtlı olabilir; bu nedenle özelliği feature detection ile koşullu olarak göstermek iyi bir pratik. Ayrıca kurumsal ağlarda güvenlik anahtarlarını tercih eden ekipler için USB/NFC/Bluetooth seçeneklerini dökümante edin.

Performans ve ölçüm

Kayıt ve giriş sürelerini ölçün; özellikle challenge üretimi ve sunucu doğrulama gecikmelerini izleyin. Hata oranlarını, başarısız biyometri denemelerini ve cihaz uyumluluk dağılımını panolara taşıyın. A/B testleri ile “passkey öncelikli” akışların dönüşüm oranlarını kıyaslayın; genellikle ilk oturum açma süreleri ve tekrar girişler belirgin şekilde hızlanır.

Geçiş stratejisi ve hesap kurtarma

Var olan parola tabanlı sisteme passkey eklerken kademeli geçiş önerilir. Önce iki faktör olarak ekleyin, ardından parolasız moda yükseltin. Hesap kurtarma için ikinci e-posta, güvenlik anahtarı veya doğrulanmış cihazda QR onayı gibi seçenekler hazırlayın. Parola sıfırlama sürecini, passkey kayıtlarını koruyacak şekilde yeniden tasarlayın ve her kritik adımda ek onay isteyin.

Sonuç

Passkeys, parolaların zayıflıklarını ortadan kaldıran, kullanıcı dostu ve güvenliği yüksek bir çözüm sunuyor. Doğru akış tasarımı, sıkı sunucu doğrulaması ve temiz bir UX ile WebAuthn’ı uygulamanıza eklemek düşündüğünüzden daha hızlı olabilir. Bugün küçük bir kullanıcı grubunda başlatın, metrikleri izleyin ve parolasız geleceğe emin adımlarla geçin.

19 Ekim 2025 Pazar

Tarayıcıda Python Çalıştırma Rehberi: WebAssembly ve Pyodide ile Adım Adım

WebAssembly (WASM) ve Pyodide sayesinde Python kodunu doğrudan tarayıcıda, sunucuya ihtiyaç duymadan çalıştırmak artık mümkün. Bu yazıda, Pyodide nedir, nasıl entegre edilir, paket yönetimi ve performans ipuçları nelerdir gibi sorulara adım adım yanıt veriyorum. Hedefimiz, hem modern web uygulamalarına Python gömmenin pratik yolunu göstermek hem de gerçek hayatta işinize yarayacak optimizasyon önerilerini sunmak.

Pyodide Nedir?

Pyodide, CPython yorumlayıcısını ve birçok bilimsel Python paketini WebAssembly’ye derleyerek tarayıcıda çalıştırmanıza olanak tanır. NumPy, Pandas, Matplotlib gibi kütüphanelerin “pure-Python” olanlarını veya WASM’a derlenmiş varyantlarını tarayıcıya getirir. Ağ bağlantısı olmasa bile, gerekli dosyalar indirildikten sonra kodunuzu yerel olarak işletir. Bu da interaktif eğitim içerikleri, gömülü veri görselleştirme, offline notebook deneyimleri ve güvenli istemci tarafı prototipleme için güçlü bir zemin sunar.

Hızlı Başlangıç: Basit Entegrasyon

Aşağıdaki minimal örnekle tarayıcıda Python çalıştırabilirsiniz. Kodu bir HTML dosyasına koyup açmanız yeterli.

<!-- Pyodide yükleyici -->
<script src="https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js"></script>
<script>
(async () => {
const pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/" });
await pyodide.runPythonAsync(`import sys; print(sys.version)`);
const result = await pyodide.runPythonAsync("sum(range(10))");
console.log("Python sonucu:", result);
})();
</script>

Burada loadPyodide ile WASM tabanlı Python ortamı yükleniyor, ardından runPythonAsync ile kod yürütülüyor. Konsolda Python sürümü ve örnek bir hesaplamanın sonucu görünecektir.

Paket Yönetimi: micropip ve Yerleşik Paketler

Pyodide, birçok popüler kütüphaneyi hazır olarak getirir. Ek bir pakete ihtiyaç duyduğunuzda micropip ile pure-Python paketleri (C uzantısı gerektirmeyenler) kolayca kurulabilir.

await pyodide.runPythonAsync(`import micropip; await micropip.install("requests")`);

NumPy veya Pandas gibi ağır paketler için Pyodide’ın yerleşik kaynaklarını kullanmak daha verimlidir. Bunlar çoğunlukla pyodide.loadPackage ile önceden yüklenebilir:

await pyodide.loadPackage(["numpy", "pandas"]);

Paket yüklemelerini sayfa ilk açılışında toplu yapmak, kullanıcı etkileşimi sırasında gecikmeleri azaltır. İlk kez yüklemede CDN’den indirme yapılırken, sonraki sayfa yenilemelerinde tarayıcı önbelleğinden faydalanılır.

Tarayıcı Dosya Sistemi ve Veri Paylaşımı

Pyodide, Emscripten’in sanal dosya sistemini (MEMFS) kullanır. JavaScript tarafındaki veriyi Python tarafına aktarmak için dosya sistemine yazmak pratik bir yöntemdir:

const csv = "a,b\\n1,2\\n3,4";
pyodide.FS.writeFile("/tmp/data.csv", csv);
await pyodide.runPythonAsync(`import pandas as pd; df = pd.read_csv("/tmp/data.csv"); print(df.sum().to_dict())`);

Alternatif olarak, doğrudan JS-Python köprüsünden yararlanabilir ve pyodide.toPy / pyodide.toJs ile veri alışverişi yapabilirsiniz. Büyük verilerde kopyalamayı en aza indirmek için bu köprüleri tercih edin.

Performans İpuçları

- Lazy yükleme yapın: İlk ekranda gerekmeyen büyük paketleri, kullanıcı etkileşimiyle tetiklenen aşamada yükleyin.
- runPython yerine runPythonAsync kullanın: Uzun süren işlemler UI’ı kilitlemesin.
- Ön ısıtma (warm-up): Sayfa yüklenir yüklenmez küçük bir Python ifadesi çalıştırmak, JIT yoksa bile modül başlatmalarını önceden yaparak ilk gerçek görevde gecikmeyi azaltır.
- Önbellekleme: CDN varlıklarını (pyodide.js, .wasm, paket indeksleri) Service Worker ile cache-first stratejisiyle saklayın. Böylece offline veya zayıf ağda bile hızlı açılış sağlanır.
- Veri boyutunu sınırlayın: Tarayıcı belleği kısıtlıdır. Tek seferde işlenen veri setlerini makul boyutta tutun ve gereksiz kopyalardan kaçının.

Güvenlik ve Sandbox

Pyodide, tarayıcının güvenli çalışma alanında koşar. Varsayılan olarak yerel dosya sistemine erişemez ve ağ istekleri tarayıcı CORS kurallarına tabidir. Üçüncü taraf paketleri yüklerken yalnızca güvendiğiniz kaynakları kullanın. Kullanıcıdan gelen Python kodunu çalıştıracaksanız, suistimali azaltmak için zaman sınırı, bellek sınırı ve izinli API listesi (allowlist) gibi korumalar düşünün.

Ne Zaman Pyodide? Ne Zaman Sunucu?

- Pyodide’ı tercih edin: Hızlı prototip, eğitim içerikleri, etkileşimli dokümantasyon, gizlilik gerektiren istemci tarafı analizler, offline kullanım senaryoları.
- Sunucuyu tercih edin: Büyük veri işlemleri, yoğun CPU bellek kullanımı, kurumsal paket bağımlılıkları, kalıcı depolama ve erişim kontrolünün kritik olduğu projeler.

Örnek Kullanım: Mini Veri Görselleştirme

Aşağıdaki örnek, küçük bir veri kümesiyle Matplotlib’i kullanır. İlk etapta paketi yükleyin, ardından grafiği base64 olarak üretip bir <img> etiketine atayabilirsiniz. (Bu yazıda görsel eklemiyoruz, ancak yaklaşım bu şekildedir.)

await pyodide.loadPackage(["matplotlib", "numpy"]);
const png = await pyodide.runPythonAsync(`import matplotlib.pyplot as plt, io, base64, numpy as np
x = np.linspace(0, 2*np.pi, 200)
y = np.sin(x)
plt.figure(figsize=(3,2), dpi=150)
plt.plot(x, y)
buf = io.BytesIO()
plt.savefig(buf, format="png", bbox_inches="tight")
base64.b64encode(buf.getvalue()).decode()`);
// document.getElementById("plot").src = "data:image/png;base64," + png;

Sonuç

Pyodide ve WebAssembly, Python’u tarayıcıya taşıyarak ön uç geliştirmeye yeni kapılar açıyor. Doğru paket yönetimi, akıllı önbellekleme ve verimli veri paylaşımıyla hem akıcı bir kullanıcı deneyimi hem de sürdürülebilir performans elde edebilirsiniz. Küçük başlayın, ihtiyaç duydukça paketleri ve optimizasyonları ekleyin. Böylece ister eğitim amaçlı mini bir laboratuvar, ister ürününüze gömülü etkileşimli bir analiz modülü geliştirin; modern webin olanaklarından en iyi şekilde yararlanırsınız.

17 Ekim 2025 Cuma

Tarayıcıda WebGPU ile Yapay Zeka Modellerini Hızlandırma: ONNX Runtime Web ile Adım Adım Rehber

WebGPU ile Tarayıcıda Yapay Zeka Neden Önemli?

WebGPU, tarayıcıda GPU’ya neredeyse yerel erişim sağlayan modern bir web standardıdır. WebGL’in grafik odaklı doğasını aşarak hesaplama iş yüklerini de hızlandırır ve makine öğrenmesi modellerini doğrudan Chrome, Edge veya Safari gibi tarayıcılarda çalıştırırken belirgin performans kazancı sunar. Bu yazıda, ONNX Runtime Web kullanarak WebGPU üzerinden nasıl hızlandırma yapabileceğinizi, gerçek dünya ipuçları ve sorun giderme önerileriyle adım adım anlatıyorum.

Ön Koşullar ve Uyumluluk

WebGPU, Chrome 113+, Edge 113+ sürümlerinde yaygın olarak desteklenir. macOS’te Metal, Windows’ta Direct3D 12, Linux’ta ise Vulkan üzerinden çalışır. Güncel bir tarayıcı kullandığınızdan emin olun. Kurumsal cihazlarda GPU sürücüleri eskiyse veya politika kısıtları varsa WebGPU adaptörü bulunamayabilir; bu durumda ONNX Runtime Web otomatik olarak WASM (WebAssembly) yedek yoluna düşebilir. Eğer eski bir tarayıcı kullanıyorsanız, chrome://flags alanında WebGPU ile ilgili ayarları gözden geçirmeniz gerekebilir; ancak çoğu güncel sürümde ekstra bir işlem yapmadan çalışır.

Ne Kuracağız? Kısa Yol Haritası

Bu rehberde bir web sayfasına ONNX Runtime Web’i entegre edip, bir görüntü sınıflandırma modelini WebGPU üzerinde çalıştıracağız. Adımlar özetle şöyle: ONNX Runtime Web’i projeye eklemek, uygun bir ONNX modeli seçmek, girdi verisini hazırlamak, executionProviders: ["webgpu"] ile oturum açmak ve sonuçları yorumlamak.

Adım 1: Projeye ONNX Runtime Web Eklemek

İki yaygın yöntem var. NPM ile kurulum için modern bir paketleyici (Vite, Webpack, Parcel) kullanabilirsiniz. Komut satırında npm i onnxruntime-web diyerek kurduktan sonra uygulamanızda import * as ort from "onnxruntime-web" ifadesini kullanın. Hızlı denemeler için CDN ile de ilerleyebilirsiniz: HTML dosyanıza ONNX Runtime Web’in CDN bağlantısını eklemek yeterli olur. Her iki yöntemde de tarayıcınızda WebGPU destekliyse arka planda otomatik olarak GPU hızlandırma devreye alınabilir.

Adım 2: Model Seçimi ve Hazırlık

Başlangıç için ONNX Model Zoo’da bulunan hafif bir model tercih edin. Örneğin MobileNet veya SqueezeNet düşük bellek tüketimiyle iyi bir başlangıç sunar. İndirdiğiniz model dosyasını (örnek: model.onnx) sunucunuzdan statik olarak servis edin. Model boyutunu mümkün olduğunca düşük tutmak hem ilk yükleme süresini hem de bellek kullanımını azaltır. FP16 dönüştürülmüş modeller, GPU bellek ayak izini düşürerek performansa katkı sağlar.

Adım 3: WebGPU ile Oturum Oluşturma

ONNX Runtime Web ile bir oturum oluştururken executionProviders: ["webgpu"] parametresini geçerek GPU hızlandırmayı istersiniz. WebGPU uygun değilse kütüphane WASM’a otomatik geçebilir. Bu aşamada önemli nokta, oturumu yalnızca bir kez oluşturmanızdır; inference işlemleri sırasında aynı oturumu tekrar tekrar kullanmak, modelin yeniden yüklenmesini ve derlenmesini önleyerek ciddi zaman kazandırır.

Adım 4: Girdi Hazırlama ve İnference

Görüntü tabanlı bir model için girdiyi modele uygun boyuta ölçekleyip normalleştirmeniz gerekir. Bu işlem genellikle şu adımlardan oluşur: görseli kanallara ayırma (RGB), piksel değerlerini 0-1 aralığına ölçekleme, ortalama/standart sapma ile normalizasyon ve tensörü NCHW biçiminde düzenleme. ONNX Runtime Web için tensör oluştururken new ort.Tensor("float32", data, [1, 3, H, W]) biçimini kullanabilirsiniz. Çıktı yüzlerce sınıf ve olasılık içeriyorsa en yüksek olasılıklı birkaç etiketi seçip kullanıcıya sunmak idealdir.

Adım 5: Performans İyileştirme İpuçları

Performansı artırmak için birkaç pratik öneri: Oturum nesnesini yeniden kullanın ve model dosyasını önbelleğe alarak ilk yükleme süresini kısaltın. Girdi verisini oluştururken gereksiz kopyalardan kaçının; aynı Float32Array tamponunu yeniden kullanmak GC yükünü azaltır. Mümkünse daha küçük çözünürlükte girişler deneyin; bazı modeller 224x224 ile tatmin edici sonuç verir. Ağır iş yüklerini Web Worker içine taşıyarak ana iş parçacığını bloklamayın; UI donmalarını önlemek için hesaplama dilimlerini requestIdleCallback veya küçük partisyonlarla planlayın. Ölçüm için performance.now() ile yükleme, ön işleme, inference ve son işlem sürelerini ayrı ayrı izleyin; darboğazı nokta atışı bularak iyileştirin.

Güvenlik, Gizlilik ve Dağıtım

Tarayıcı içinde yerel inference çalıştırmak, verilerin sunucuya gitmeden işlenmesini sağlar; bu da gizlilik ve gecikme (latency) açısından avantajdır. WASM yedek yolunda iş parçacıkları ve SIMD kullanmayı planlıyorsanız COOP/COEP başlıklarıyla cross-origin isolated bir yapılandırma gerekir. İç ağda veya kurumsal ortamlarda dağıtım yaparken GPU sürücü sürümlerini ve tarayıcı versiyonlarını standardize etmek, destek çağrılarını ciddi ölçüde azaltır.

Yaygın Hatalar ve Çözümler

“Adapter is null” veya “No WebGPU device found” hataları alıyorsanız tarayıcınızı ve ekran kartı sürücünüzü güncelleyin; sanal makinelerde WebGPU kısıtlı olabilir. “Out of memory” uyarılarında giriş boyutunu küçültün, modelin FP16 sürümüne geçin veya daha hafif bir mimari deneyin. “Invalid model input shape” hatası, tensör boyutlarıyla modelin beklediği şeklin uyuşmadığını gösterir; modelin giriş ismini ve beklenen boyutları kontrol edin. WASM’a düşüşte performans çok geriliyorsa, WebGPU’nun gerçekten etkinleştiğini doğrulamak için oturum seçeneklerini ve tarayıcı destek sayfalarını inceleyin.

Gerçek Dünya Senaryoları

Perakende uygulamalarında raf denetimi veya barkod dışı ürün tanıma gibi görevler, mağaza içi tabletlerle çevrimdışı çalıştırılabilir. Eğitim teknolojilerinde çizim veya laboratuvar deneylerinde görüntü analizi, öğrenci cihazlarında gecikme olmadan yapılabilir. Yayıncılıkta canlı metin filtreleme veya basit duygu analizi, kullanıcı tarayıcısında gerçekleşerek sunucu maliyetlerini düşürür.

Sonuç ve Öneriler

WebGPU, tarayıcıda yapay zeka deneyimini yeni bir seviyeye taşıyor. ONNX Runtime Web ile birlikte kullanıldığında, çeşitli cihaz ve tarayıcı kombinasyonlarında tatmin edici performans ve düşük gecikme elde etmek mümkün. Küçük ve optimize edilmiş bir model, doğru ön işleme adımları ve tek seferde başlatılan bir oturum mimarisi, projelerinize stabilite ve hız kazandırır. İlk prototipinizi basit bir görüntü sınıflandırma modeliyle kurup, ardından model boyutu, giriş çözünürlüğü ve iş parçacığı stratejileri üzerinde iterasyon yaparak prodüksiyon seviyesine güvenle geçebilirsiniz.

23 Eylül 2025 Salı

Next.js 14’te Server Actions ile Güvenli Form ve Dosya Yükleme: Adım Adım Rehber

Giriş

Next.js 14 ile birlikte hayatımıza giren Server Actions, form işlemleri ve veri mutasyonlarını API katmanı yazmadan, doğrudan sunucuda çalıştırılabilir fonksiyonlarla yönetmemizi sağlıyor. Bu yaklaşım hem güvenliği artırıyor hem de geliştirici deneyimini iyileştiriyor. Bu yazıda, App Router mimarisi altında Server Actions kullanarak güvenli form işleme ve dosya yükleme senaryosunu adım adım ele alacağız. Ayrıca performans, SEO ve güvenlik tarafındaki püf noktalarına da değineceğiz.

Önkoşullar ve Kurulum

Başlamadan önce Node.js 18+ ve Next.js 14 ortamınız hazır olmalı. Projeyi TypeScript ile başlatmanızı öneririm; tip güvenliği hem sunucu eylemlerinde hem de form verisi doğrulamada büyük kolaylık sağlar. App Router (app/ dizini) kullanıyorsanız, sayfalarınız React Server Components olarak varsayılan şekilde sunulur; bu sayede istemciye daha az JavaScript gönderilir ve SEO performansınız artar.

Server Actions Mantığı

Server Actions, bir fonksiyonun başına "use server" yönergesi eklenerek sunucuda çalıştırılmasını sağlar. Bu fonksiyonları doğrudan formun action props’una bağlayabilir ve formData alabilirsiniz. Ek bir API route yazmanız gerekmez. İş mantığı sunucuda kaldığı için token, bağlantı string’i ve gizli anahtarlar istemciye sızmaz. İşlem sonrası önbelleği tazelemek için revalidatePath() veya revalidateTag() çağırabilirsiniz.

Form Doğrulama Stratejisi

Doğrulama iki katmanda yapılmalı: istemci tarafında kullanıcı deneyimini iyileştiren anlık kontroller (örneğin e-posta formatı), sunucu tarafında ise kaynak güvenliği sağlayan kesin doğrulamalar. Server Actions içinde zod gibi bir şema doğrulama kütüphanesi kullanarak tip güvenli ve anlaşılır hata mesajları üretin. Hataları action’dan geriye döndürüp formda kullanıcıya göstermek, klasik API isteklerine göre daha yalın bir akış sağlar.

Dosya Yükleme: Route Handler mı, Server Action mı?

Basit senaryolarda formunuzdaki dosya alanını Server Action içinde formData.get("file") ile alabilirsiniz. Ancak büyük dosyalar, virüs taraması veya üçüncü taraf depolama (S3, R2 vb.) gerekiyorsa Route Handlers (app/route.ts) tercih edin. Bu sayede streaming ile bellek kullanımını kontrol edebilir, sınırları (limits) ve doğrulamayı daha esnek yönetebilirsiniz. Platformunuza göre runtime seçimi önemlidir: Node özelliklerine ihtiyaç varsa export const runtime = "nodejs" kullanın; global edge ağı üzerinde düşük gecikme istiyorsanız "edge" seçeneğini değerlendirin.

Adım Adım Senaryo: Profil Formu + Avatar Yükleme

1) Formu Tasarlayın: İsim, e-posta, kısa bio ve avatar dosya alanı ekleyin. Geriye dönüt için alan bazlı hata mesajları ve formun gönderim durumunu göstermek üzere bir yükleniyor göstergesi ekleyin.

2) Server Action Yazın: "use server" ile başlayan saveProfile fonksiyonu, formData içinden girişleri okur. zod ile isim ve e-posta zorunlu, bio uzunluğu sınırlı olacak şekilde doğrulayın. Doğrulama hatalarını sade bir nesne olarak geri döndürün.

3) Avatar İçin Doğrulama: MIME türü (image/jpeg, image/png), dosya boyutu (ör. 2 MB sınır), ve görüntü boyutları (ör. 1024x1024 üstü reddedilsin) kontrol edin. Şüpheli içerik için içerik taraması gerekiyorsa, asenkron bir kuyruk (örn. SQS, Pub/Sub) veya webhook tabanlı işleme düşünebilirsiniz.

4) Depolama Stratejisi: Büyük dosyaları doğrudan Server Action üzerinden aktarmak yerine, istemcide önceden imzalı URL (pre-signed URL) alıp doğrudan depolamaya yüklemek daha verimlidir. Bu yaklaşım, sunucu trafiğini azaltır ve edge bölgelerinde daha hızlıdır. Ardından Server Action sadece meta veriyi (dosya URL’si) veritabanına kaydeder.

5) Önbellek ve Yeniden Doğrulama: Profil sayfanız statikse bile güncelleme sonrası revalidatePath("/profil") ile görünümü anında tazeleyin. Eğer profil verilerini cache tag ile etiketlediyseniz, revalidateTag("profil") çağrısı da etkili olacaktır.

6) UX İyileştirmeleri: Progressive enhancement mantığıyla, JavaScript kapalıyken dahi form çalışmalı; JS açıkken ise iyileştirmeler devreye girmeli. useFormStatus ile buton durumunu yönetin, belirli alanlar için optimistic UI uygulayın.

Güvenlik İpuçları

CSRF: Server Actions form gönderiminde varsayılan olarak korumalı bir yol sağlar; yine de hassas işlemlerde ek kontrol (ör. origin doğrulama) uygulayın. Rate Limiting: Brute-force girişimleri için IP veya token bazlı sınırlama ekleyin. Dosya Güvenliği: İçerik türü ve boyut kontrolü zorunlu; antivirüs taraması ve izole geçici depolama ile zinciri güçlendirin. Gizli Anahtarlar: Tüm sırları process.env üzerinden sunucuda okuyun; istemciye sızdırmayın.

Performans ve SEO

App Router ile sayfalarınız server-rendered çalıştığı için ilk yükleme süresi ve SEO performansı güçlüdür. Server Actions, veri mutasyonunu aynı kökten ele aldığından fazladan JSON döndürme ve istemci durum yönetimi yükünü azaltır. Yalnızca değişmesi gereken segmentleri yeniden doğrulamak, gereksiz yeniden oluşturma maliyetini düşürür. Görsel ve statik varlıklar için HTTP cache başlıklarını doğru ayarlayın, kritik CSS’i minimal tutun.

Hata Ayıklama ve Test

Geliştirme sırasında action’larınızın giriş ve çıkışlarını ayrıntılı loglayın; hassas verileri loglardan uzak tutun. Birim testlerde, doğrulama şemalarını ve yan etkisiz iş mantığını izole ederek test edin. Uçtan uca testlerde (Playwright) gerçekçi form doldurma ve dosya yükleme akışlarını, hata durumlarını ve erişilebilirlik kontrollerini (klavye navigasyonu, ARIA etiketleri) kapsayın.

Sonuç

Next.js 14’te Server Actions, form ve dosya yükleme gibi günlük iş akışlarını basitleştirirken güvenlik ve performans avantajı da sağlar. Doğrulama, depolama ve önbellek stratejilerini doğru kurguladığınızda daha az kodla daha ölçeklenebilir bir çözüm elde edersiniz. Küçük bir profil formundan kurumsal bir içerik yönetim sistemine kadar aynı ilkelere dayanarak karmaşık senaryoları dahi güvenle kurgulayabilirsiniz.

12 Eylül 2025 Cuma

Next.js 14’te Server Actions ile Güvenli Form ve Dosya Yükleme: Adım Adım Rehber

Next.js 14 ile birlikte gelen Server Actions, form gönderimlerini sunucu tarafında güvenle işlemek ve istemci kodunu sadeleştirmek için güçlü bir seçenek sunar. Bu rehberde, e-posta alanı içeren basit bir formu ve güvenli dosya yükleme akışını, Zod ile doğrulama yaparak adım adım kuracağız. Hedefimiz, gereksiz API katmanları oluşturmadan, tek bir action ile temiz ve ölçeklenebilir bir çözüm elde etmek.

Server Actions yaklaşımı; XHR/fetch kodlarını azaltır, React Server Components ile uyumlu çalışır ve SSR/ISR stratejilerine zarar vermeden form iş akışlarını basitleştirir. Dosya işlemlerinde ise tür ve boyut kontrolüyle güvenlik yüzeyini daraltır. Vercel gibi platformlarda çalışırken /tmp gibi geçici dizinlerin kullanımı mümkündür; kalıcı depolama için S3 benzeri servisler önerilir.

Gereksinimler

- Node.js 18+ ve Next.js 14+

- Paket yöneticisi (pnpm, npm veya yarn)

- (İsteğe bağlı) Zod ile şema tabanlı doğrulama

Kurulum ve Hazırlık

Yeni bir proje başlatalım:

npx create-next-app@latest next14-server-actions
cd next14-server-actions
pnpm add zod

Server Actions Next.js 14’te varsayılan olarak desteklenir. Projenizde gerekirse aşağıdaki gibi bir yapılandırma ile istek boyutunu kontrol edebilirsiniz (opsiyonel):

// next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverActions: {
      bodySizeLimit: '6mb' // FormData sınırı (opsiyonel)
    }
  }
};
export default nextConfig;

Server Action: Doğrulama ve Yükleme

Aşağıdaki action, e-postayı Zod ile doğrular, dosya türünü ve boyutunu kontrol eder, ardından dosyayı bir hedef dizine yazar. Geliştirme ve Vercel üzerinde test için varsayılan olarak /tmp kullanılabilir.

// app/actions.ts
'use server';

import { z } from 'zod';
import { writeFile } from 'fs/promises';
import path from 'path';
import crypto from 'crypto';

const schema = z.object({
  email: z.string().email()
});

// Node.js API'larına ihtiyacımız olduğundan runtime'ı Node olarak zorlayalım (opsiyonel).
export const runtime = 'nodejs';

export async function uploadFile(formData: FormData) {
  const email = String(formData.get('email') || '');
  const file = formData.get('file');

  const parsed = schema.safeParse({ email });
  if (!parsed.success) {
    return { ok: false, error: 'Geçersiz e-posta adresi.' };
  }

  if (!(file instanceof File)) {
    return { ok: false, error: 'Dosya bulunamadı.' };
  }

  const allowed = ['image/png', 'image/jpeg', 'application/pdf'];
  if (!allowed.includes(file.type)) {
    return { ok: false, error: 'İzin verilmeyen dosya türü.' };
  }

  const MAX = 5 * 1024 * 1024; // 5MB
  if (file.size > MAX) {
    return { ok: false, error: 'Dosya boyutu 5MB sınırını aşıyor.' };
  }

  const arrayBuffer = await file.arrayBuffer();
  const buffer = Buffer.from(arrayBuffer);

  const filename =
    crypto.randomBytes(8).toString('hex') + '-' + (file.name || 'upload');
  const destDir = process.env.UPLOAD_DIR || '/tmp';
  const destPath = path.join(destDir, filename);

  await writeFile(destPath, buffer);

  return { ok: true, path: destPath };
}

Form Bileşeni ve Kullanım

Formun action özelliğine doğrudan server action’ı vererek kolayca bağlayabiliriz. Bu sayede client tarafında ekstra fetch mantığına gerek kalmaz.

// app/page.tsx
import { uploadFile } from './actions';

export default function Page() {
  return (
    <main style={{ maxWidth: 560, margin: '40px auto', fontFamily: 'sans-serif' }}>
      <h1>Dosya Yükleme Formu</h1>
      <form action={uploadFile}>
        <label>E-posta</label>
        <input type="email" name="email" required placeholder="[email protected]" />

        <label style={{ display: 'block', marginTop: 12 }}>Dosya (PNG/JPEG/PDF)</label>
        <input type="file" name="file" accept="image/png,image/jpeg,application/pdf" required />

        <button type="submit" style={{ marginTop: 16 }}>Gönder</button>
      </form>
      <p style={{ fontSize: 12, color: '#666', marginTop: 12 }}>
        Not: Demo amaçlı yüklemeler geçici dizine kaydedilir.
      </p>
    </main>
  );
}

İsterseniz kullanıcı deneyimini iyileştirmek için Client bileşeninde submit durumunu gösterebilir, form sonucunu Server Action’dan dönen nesneye göre ekrana yazdırabilirsiniz. Daha gelişmiş bir deneyim için useFormStatus ve useFormState yardımcılarını değerlendirebilirsiniz.

Güvenlik ve En İyi Uygulamalar

- Dosya türlerini beyaz listeyle sınırlandırın (PNG, JPEG, PDF gibi). Gerekirse MIME kontrolüne ek olarak sihirli bayt (magic bytes) kontrolü uygulayın.

- Boyut limiti belirleyin ve Next.js yapılandırmasında body limiti ile eşleştirin.

- Kalıcı depolama için S3 veya benzeri bir objeler deposu kullanın; dosya adlarını çakışmaları önlemek için hashleyin.

- İşlem süresi ve ortam kısıtları için Node.js runtime tercih edin; kenar (Edge) iş yüklerinde dosya manipülasyonu yerine imzalı URL yaklaşımı kullanın.

Çalıştırma ve Dağıtım

Geliştirme ortamında başlatmak için:

pnpm dev

Vercel’e dağıtırken ek bir API katmanına ihtiyaç duymadan aynı kod çalışır. Yalnızca kalıcı depolama kullanacaksanız ilgili servis kimlik bilgilerini çevresel değişkenlerle (ör. S3_ACCESS_KEY, S3_BUCKET) eklemeyi unutmayın.

Sonuç olarak, Next.js 14’te Server Actions ile güvenli ve performanslı bir dosya yükleme akışını, sade bir mimariyle hayata geçirebilirsiniz. Zod tabanlı doğrulama, sınırlı dosya türleri ve boyut kontrolleri ile riskleri minimize ederken, kullanıcıya yalın bir deneyim sunarsınız.

24 Ağustos 2025 Pazar

Rust ile WebAssembly (WASM) Performans Optimizasyonu: Adım Adım Rehber

Giriş — Neden Rust + WASM?

Rust ile WebAssembly (WASM) birbirini tamamlayan iki teknoloji: Rust'ın bellek güvenliği ve sıfır maliyet soyutlamaları, WASM'in tarayıcıda çalışabilen düşük seviyeli modülleriyle birleştiğinde hem performans hem de güvenlik sağlar. Bu rehberde, Rust ile yazılmış bir WASM modülünü oluştururken karşılaşacağınız temel yapılandırmaları, performans tuzaklarını ve optimizasyon tekniklerini adım adım ele alacağım.

Hazırlık ve araçlar

İhtiyacınız olanlar: Rust toolchain (rustup), wasm-pack veya cargo + wasm-bindgen, binaryen/wasm-opt (wabt ve binaryen paketleri) ve bir frontend paketleyici (ör. webpack veya Vite). Başlangıç için terminalde rustup target add wasm32-unknown-unknown, cargo install wasm-pack ve wasm-opt kurulumunu yapın. Bu araçlar derleme, bağlama ve ikili optimizasyon süreçlerinde kritik öneme sahip.

Basit bir örnek: fonksiyonları dışa aktarma

Rust'ta basit bir fonksiyonu WASM'e dışa aktarmak için wasm-bindgen kullanın. Örnek:

use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sum(a: i32, b: i32) -> i32 {
    a + b
}

Bu kodu wasm-pack build --target web ile derleyip, tarayıcı tarafında import ederek kullanabilirsiniz. Ancak performans için dikkat edilmesi gerekenler yalnızca derlemek değildir; nasıl çağırdığınız ve veri taşıdığınız da önemlidir.

Performans odaklı ipuçları

1) JS↔WASM sınırını minimize edin: Her JS-WASM çağrısı CPU yükü ve marjinal overhead getirir. Küçük, sık yapılan çağrılar yerine veri blokları gönderip tek seferde işlemek genelde daha verimlidir.

2) Bellek yönetimi: WASM lineer belleği kullanır. Büyük veri için Vec kullanıp pointer ve uzunluk dönerek SharedArrayBuffer/ArrayBuffer üzerinden doğrudan erişim sağlayın. Böylece kopyalamaları azaltırsınız.

3) Veri tiplerini basit tutun: Karmaşık nesne serileştirmeleri yerine ikili formatlar veya sabit tipli diziler kullanın. JSON yerine biner format performansı belirgin şekilde artırır.

4) SIMD ve multi-threading: Tarayıcılar artık SIMD ve Threads için deneysel destek sunuyor. simd128 ve atomics özelliklerini kullanmak büyük hesaplamalarda hız verir, ancak Cross-Origin-Opener-Policy (COOP) ve Cross-Origin-Embedder-Policy (COEP) başlıkları gerektirir.

Derleme ve optimizasyon bayrakları

Release derlemelerinde cargo build --release veya wasm-pack build --release kullanın. Ek olarak RUSTFLAGS ile LTO (link time optimization) ve hedef özelliklerini açabilirsiniz:

export RUSTFLAGS="-C opt-level=z -C linker-plugin-lto -C codegen-units=1"
wasm-pack build --release

Opt-level=z dosya boyutuna odaklanır; -C opt-level=3 ise hız odaklıdır. Ardından wasm-opt -Oz ile ikiliyi küçültün ve performans profili doğrultusunda -O3 seçeneğini değerlendirin.

Boyut azaltma ve dağıtım

WASM modüllerini gzip veya brotli ile sıkıştırıp sunmak yükleme süresini büyük ölçüde azaltır; brotli genelde daha iyi sıkıştırma sağlar. Ayrıca kullanılmayan kodu elimine eden tree-shaking ve cargo features ile gereksiz bağımlılıkları kaldırın. wasm-snip veya cargo-udeps gibi araçlar gereksiz kodu tespit etmekte yardımcı olur.

Profiling ve ölçme

Performans iyileştirmelerinin etkisini ölçmeden uygulamak yanıltıcı olabilir. Tarayıcıların Performans/Profiler araçları, WASM hotspot'larını görmenizi sağlar. Ayrıca wasm-objdump ve wasm-validate ile ikiliyi analiz edin. Gerçek dünya yüklerini taklit eden benchmark'lar oluşturun; mikro benchmark'lar yanıltıcı olabilir.

Sık yapılan hatalar ve çözüm önerileri

- Çok küçük fonksiyonları sık çağırmak: Bunları birleştirin veya toplu işleyin. - Aşırı kopyalama: Bellek penceresi kullanarak kopyalamayı azaltın. - Yanlış derleme bayrakları: test ve release davranışını karıştırmayın; release ile ölçün. - COOP/COEP gereksinimlerini göz ardı etmek: Threaded WASM için server başlıklarını doğru ayarlayın.

Sonuç

Rust + WASM ile yüksek performanslı web modülleri oluşturmak mümkün ve sürdürülebilir. Temel prensipler: JS-WASM sınırını akıllıca yönetmek, bellek erişimini optimize etmek, doğru derleme ve ikili optimizasyonları kullanmak ve sonuçları dikkatle ölçmektir. Bu rehber, bir başlangıç yolu sunar; gerçek uygulamalar için spesifik profil verilerine dayanarak ince ayar yapmanız en iyi sonucu verecektir.

22 Ağustos 2025 Cuma

Rust ile WebAssembly (WASM) Kullanarak Yüksek Performanslı Web Uygulamaları Geliştirme

Giriş

Web uygulamalarında CPU yoğunluklu işlemleri tarayıcıya taşımak gerektiğinde WebAssembly (WASM) önemli bir seçenek sunar. Rust ise bellek güvenliği, performans ve derleyici garantileriyle WASM için sık tercih edilen dillerden biridir. Bu yazıda, Rust ile WASM geliştirirken dikkat edilmesi gereken temel adımları, optimizasyonları ve üretime hazırlık süreçlerini sade ve uygulamalı şekilde ele alacağım.

Hazırlık ve araçlar Öncelikle sisteminizde Rust kurulu olmalı. rustup üzerinden güncel toolchain'i kurduktan sonra hedef olarak wasm32-unknown-unknown eklenir: rustup target add wasm32-unknown-unknown. Ardından proje paketlemeyi kolaylaştıran wasm-pack veya doğrudan wasm-bindgen tercih edilebilir. İyi bir optimizasyon için Binaryen'in wasm-opt aracını da kurmanızı öneririm.

Basit bir başlangıç örneği

Yeni bir kütüphane projesi oluşturup JavaScript ile çağırılabilir fonksiyonler yazalım. Cargo projesi oluşturduktan sonra Cargo.toml'a wasm-bindgen ekleyin ve Rust kodunda şu örneği kullanın:

use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn heavy_compute(n: u32) -> u64 { (0..n as u64).map(|x| x * x).sum() }

Derleme aşaması için iki yaygın yol var: wasm-pack build --target web --release ile paketleyip doğrudan bir modül olarak kullanmak veya cargo build --target wasm32-unknown-unknown --release sonrası wasm-bindgen CLI ile çıktıyı hazırlamak. wasm-pack yeni başlayanlar için entegrasyon kolaylığı sağlar.

Performans ipuçları

WASM ve Rust kombinasyonunda performansı etkileyen başlıca noktalar şunlardır: bellek tahsisi, JavaScript ile sınır-maliyetli geçişler, veri kopyalama ve algoritma seçimi. Fonksiyonlar arasında sık sık büyük veri yapıları geçiriyorsanız, işinizi Rust içinde bitirip tek bir sonuç döndürmeye çalışın. JS-Rust dönüşümlerinde serializasyon maliyetini azaltmak için serde-wasm-bindgen kullanabilirsiniz.

Ayrıca, release derlemelerinde --release kullanmak ve mümkünse wasm-opt -Oz ile sıkıştırma yapmak önemlidir. Örnek: wasm-opt pkg/your_crate_bg.wasm -Oz -o pkg/your_crate_bg.wasm. Bunun yanında wasm-strip ile gereksiz sembolleri kaldırabilirsiniz.

Tarayıcı özellikleri: SIMD ve threads

WASM SIMD ve threads (Web Workers + SharedArrayBuffer) performansı ciddi oranda artırabilir, ancak tarayıcı desteği ve güvenlik başlıkları gerektirir. Threads kullanmak için sunucunuzda COOP/COEP başlıklarını ayarlayarak cross-origin isolation sağlamalısınız. SIMD ise belirli tarayıcı sürümlerinde etkin olur; derleme sırasında RUSTFLAGS="-C target-feature=+simd128" gibi bayraklar kullanılabilir ve hedef desteğine dikkat edilmelidir.

Hata ayıklama ve geliştirici deneyimi

WASM çıktıları doğrudan okunması zor olabilir. Rust tarafında panik mesajlarını tarayıcı konsoluna almak için console_error_panic_hook kullanın: console_error_panic_hook::set_once(). Kaynak haritaları (source maps) ile Rust kaynaklarına dönebilmek için ilgili araçları etkinleştirin. Ayrıca wasm-bindgen çıktılarındaki JS wrapper'ları incelenebilir; onlar JS tarafında yapılması gereken hafif köprüleri gösterir.

Dağıtım ve boyut azaltma

Üretim ortamında paket boyutu ve yükleme süresi önemlidir. Aşağıdaki adımlar genelde iyi sonuç verir: release derleme, wasm-opt -Oz, gzip ya da brotli sıkıştırma, ve JS paketleyicide tree-shaking. Eğer proje büyükse, kritik olmayan kodu WebAssembly yerine JS veya dinamik modüller olarak ayırmak da yararlı olabilir.

Frameworkler ve örnekler

Tek başına WASM kullanmak kadar Yew veya Seed gibi Rust tabanlı çerçevelerle SPA geliştirmek de mümkün. Bu çerçeveler geliştirme deneyimini hızlandırır ancak çıktı büyüklüğünü etkileyebilir; dolayısıyla ön testler yapın ve yalnızca ihtiyaç duyulan parçaları kullanın.

Sonuç Rust + WebAssembly modern web uygulamalarında performansı artırmak için güçlü bir kombinasyon sunar. Ancak başarı için derleme ve optimizasyonda dikkatli olmak, JS-etkileşim maliyetlerini minimize etmek ve tarayıcı özellikleri ile kısıtlamalarını bilmek gerekir. Küçük bir modül ile başlayın, profilleyin ve adım adım üretim güvenliğine geçin.