güvenlik etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
güvenlik etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

9 Ağustos 2026 Pazar

Mark Zuckerberg’in Yatının Yardım Çağrısına Yanıt Vermemesi ve Skiffin Kurtarılması

Alaska’nın Farragut Koyu yakınlarında, yakıtı tükenen küçük bir skiff denizcileri zor durumda bıraktı. Kıyı Koruma Kuvvetleri, saat 09:56’da acil bir kurtarma talebi yayınladı. O an bölgede, Mark Zuckerberg ve eşi Priscilla Chan’ın sahibi olduğu “The Launchpad” adlı yat bulunuyordu. Ancak yat, skiffin gönderdiği radyo çağrısına yanıt vermedi.

“The Launchpad”teki ekip, çağrının geldiği anda gemide değildi. Sözcü Brian Baker, “Kıyı Koruma Kuvvetleri’nin belirttiği gibi, gemi tehlike altında değildi; ekip farklı bir radyo kanalıyla iletişime geçtiğinde kurtarma operasyonu zaten başlamıştı” açıklamasını yaptı. Bu açıklama, yatın neden yanıt vermediği konusunda kısmi bir açıklama sundu.

Skiffin kurtarılması, “Wilderness Legacy” adlı bir cruise gemisinin müdahalesiyle gerçekleşti. Gemi, Farragut Koyu’na yönelerek yakıtı biten skiffi alıp güvenli bir bölgeye çekti. Olay sırasında “The Launchpad” skiffin yakınında durdu, ardından koyun girişine yakın bir noktaya hareket etti; fakat bu hareketler kurtarma talebine yanıt olarak algılanmadı.

Bu durum, denizcilik sektöründe insani yardım ve güvenlik protokollerinin ne kadar kritik olduğunu bir kez daha gözler önüne serdi. Yardım çağrısına yanıt vermeyen bir lüks yat, sektördeki güvenlik standartlarının ve iletişim prosedürlerinin yeniden gözden geçirilmesi gerektiği tartışmalarını ateşledi.

Olayın Detayları

Kıyı Koruma Kuvvetleri, skiffin acil durum sinyalini aldıktan kısa bir süre sonra “Wilderness Legacy”ye yönlendirme yaptı. Gemi, skiffin bulunduğu konuma hızla ilerledi ve mürettebatı güvenli bir şekilde tahliye etti. “The Launchpad” ise aynı bölgede bulunmasına rağmen, radyo frekansına yanıt vermedi ve kurtarma ekipleriyle doğrudan temas kurmadı.

Sözcünün verdiği bilgiye göre, “The Launchpad” ekibi farklı bir radyo kanalını kullandığı için Kıyı Koruma Kuvvetleri’nin yayınladığı çağrıya ulaşamamış olabilir. Ancak bu durum, lüks yatların acil durum iletişim protokollerine uyum sağlaması gerektiğini ortaya koyuyor.

Denizcilik Sektöründe Güvenlik Protokollerinin Önemi

Denizcilik faaliyetlerinde, özellikle acil durumlarda hızlı ve etkili iletişim hayati önem taşır. Olay, teknolojik altyapının ve standart iletişim kanallarının tüm gemiler tarafından aynı şekilde kullanılmasının gerekliliğini vurguladı. Güvenlik protokolleri, yalnızca büyük gemiler için değil, lüks yatlar gibi daha küçük ölçekli deniz araçları için de geçerli olmalı.

Güvenlik prosedürlerinin sıkı bir şekilde uygulanması, can ve mal kaybı riskini azaltır. “The Launchpad” gibi yüksek profilli gemilerin, acil durum sinyallerine anında yanıt vermesi, sektördeki güvenlik algısını güçlendirebilir.

Teknoloji ve İletişim Kullanımının Rolü

Olay, denizcilik sektöründe AIS (Automatic Identification System) ve radyo frekanslarının izlenmesinin önemini bir kez daha gösterdi. AIS verileri, “The Launchpad”in skiffin yakınında durduğunu ve ardından koyun girişine yöneldiğini kanıtladı. Bu veriler, kurtarma operasyonlarının şeffaflığını artırırken, aynı zamanda gemi sahiplerinin sorumluluklarını da netleştiriyor.

İletişim kanallarının standartlaştırılması, acil durumlarda bilgi akışının kesintisiz sürdürülmesini sağlar. “Wilderness Legacy”nin hızlı müdahalesi, doğru iletişim altyapısının ne kadar etkili olabileceğinin bir örneği oldu.

Skiffin Kurtarılması ve Gelişmeler

Skiffin mürettebatı, “Wilderness Legacy”nin müdahalesi sayesinde güvenli bir şekilde tahliye edildi. Olay sırasında, yolculuk yapan bir yolcu olan Michael Love, sosyal medya üzerinden skiffin durumunu paylaştı ve “The Launchpad”in yakınlarda olduğunu ancak yanıt vermediğini belirtti. Bu paylaşım, olayın kamuoyunda geniş yankı bulmasına yol açtı.

Görsel materyaller, Getty Images’tan Sylvain Lefevre tarafından çekildi; fotoğraflar “The Launchpad”in konumunu ve teknik özelliklerini belgeledi. Bu görseller, denizcilik uzmanlarının olayın mekânsal dinamiklerini analiz etmesine yardımcı oldu.

Sektörel Sonuçlar

Mark Zuckerberg’in yatının yardım çağrısına yanıt vermemesi, denizcilik sektöründe güvenlik protokollerinin ve insani yardım ilkelerinin yeniden değerlendirilmesi gerektiğini ortaya koydu. Olay, lüks yatların da acil durum iletişim standartlarına uyması gerektiği konusunda bir farkındalık yarattı.

Denizcilik otoriteleri, benzer durumların önüne geçmek amacıyla tüm gemilerin aynı radyo frekanslarını izlemelerini ve acil durum sinyallerine anında yanıt vermelerini zorunlu kılacak düzenlemeler üzerinde çalışabilir. Böyle bir yaklaşım, gelecekte benzer vakaların yaşanma ihtimalini azaltabilir.

Sonuç olarak, “The Launchpad”in yanıt vermemesi, denizcilik güvenliği, iletişim teknolojileri ve acil durum protokollerinin bir bütün olarak ele alınması gerektiğini gösterdi. Olay, sektördeki paydaşların sorumluluklarını yeniden gözden geçirmesine ve daha etkili bir kurtarma altyapısı oluşturulmasına zemin hazırladı.

Kaynak: theverge.com

13 Haziran 2026 Cumartesi

DevSecOps Pipelines with Jenkins and GitLab: Güvenlik ve Verimlilik için Entegre Bir Yaklaşım

DevSecOps, geliştirme, güvenlik ve operasyon ekiplerini bir araya getiren bir yaklaşım olarak dikkat çekiyor. Bu yaklaşımın temelinde, güvenlik ve kalite kontrollerinin CI/CD pipeline'larına entegre edilmesi yer alıyor. Bu makalede, Jenkins ve GitLab gibi popüler araçları kullanarak DevSecOps pipeline'ları oluşturmanın teknik ayrıntılarına odaklanacağız.

DevSecOps Pipeline'ları Oluşturma

DevSecOps pipeline'ları oluştururken, geliştirme, test, güvenlik ve dağıtım aşamalarını bir araya getirmek gerekiyor. Jenkins ve GitLab, bu aşamaları entegre etmek için powerful araçlar sunuyor. Jenkins, CI/CD pipeline'larını yönetmek için kullanılırken, GitLab, versiyon kontrol ve geliştirme işlemlerini yönetmek için kullanılıyor.

Jenkins ve GitLab Entegrasyonu

Jenkins ve GitLab entegrasyonu, DevSecOps pipeline'larını oluşturmak için kritik bir adımdır. Jenkins, GitLab'dan geliştirme ve test sonuçlarını alabilir ve bunları güvenlik ve kalite kontrollerine entegre edebilir. Bu entegrasyon, otomatik test ve güvenlik kontrollerinin yapılmasını sağlar ve hata oranlarını azaltmaya yardımcı olur.

Örneğin, Jenkins, GitLab'dan kod değişikliklerini alabilir ve bunları otomatik test ve güvenlik kontrollerine tabi tutabilir. Bu, güvenlik açıklarını erken tespit etmeyi ve hata oranlarını azaltmayı sağlar.

Sonuç

DevSecOps pipeline'ları, güvenlik ve kalite kontrollerinin CI/CD pipeline'larına entegre edilmesi için powerful bir araç sunuyor. Jenkins ve GitLab gibi araçları kullanarak, DevSecOps pipeline'ları oluşturabilir ve güvenlik ve kalite kontrollerini otomatikleştirebilirsiniz. Bu, hata oranlarını azaltmaya yardımcı olur ve güvenlik açıklarını erken tespit etmeyi sağlar.

13 Şubat 2026 Cuma

Ring ve Flock Safety Ortaklığının Sonu: Görüntüleme Teknolojisi ve Güvenlik

2025 yılında, teknoloji dünyasırapid bir şekilde gelişmeye devam ediyor. Özellikle güvenlik ve gözetim teknolojileri alanında önemli adımlar atılıyor. Ancak, bu gelişmelerin beraberinde getirdiği etik ve gizlilik endişeleri de artıyor. Ring ve Flock Safety arasındaki ortaklığın sona ermesi, bu endişelerin bir yansıması olarak görülebilir.

Görüntüleme Teknolojisi ve Güvenlik

Görüntüleme teknolojisi, güvenlik amaçlı kullanıldığında önemli faydalar sunabilir. Örneğin, suçların çözülmesinde, kamu güvenliğinin sağlanmasında ve trafik kontrolünde efektif bir araç olabilir. Ancak, bu teknolojilerin kullanımının beraberinde getirdiği riskler de yok değil. Gizlilik ihlalleri, veri güvenliği sorunları ve ayrımcılık endişeleri, bu teknolojilerin kullanımını düzenlemek için önemli nedenler olarak görülüyor.

Flock Safety ve Ring Ortaklığı

Flock Safety, bir gözetim teknoloji şirketidir ve主要 olarak kanun uygulama kurumlarıyla çalışır. Ring ise, ev güvenlik sistemleri için bir marka olarak bilinir. Bu iki şirket arasındaki ortaklık, Ring'in ürünlerinde Flock Safety'nin teknolojisini kullanması anlamına geliyordu. Ancak, bu ortaklık kısa ömürlü oldu ve Ring, yoğun geri bildirimler sonrasında bu ortaklığı sonlandırma kararı aldı.


// Örnek bir gözetim sistemi kod bloğu
import cv2

# Kamera açma
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Görüntü işleme
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('frame', gray)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Kamera kapatma
cap.release()
cv2.destroyAllWindows()

Bu karar, kamuoyunda önemli bir tartışmaya neden oldu. Bir yandan, gözetim teknolojilerinin potansiyel faydaları vurgulandı; diğer yandan, bu teknolojilerin kullanımının beraberinde getirdiği riskler ve endişeler dile getirildi.

Gelecek Perspektifi

Gelecek perspektifinde, gözetim teknolojilerinin kullanımının daha dikkatli bir şekilde düzenlenmesi gerektiği açık. Bu teknolojilerin potansiyel faydaları, risklerine kıyasla daha büyük olmalı ve toplumun geniş kesimlerinin güvenliği ve gizliliği korunmalıdır. Ring ve Flock Safety arasındaki ortaklığın sona ermesi, bu teknolojilerin kullanımını daha dikkatli bir şekilde değerlendirmemiz gerektiğini gösteren önemli bir örnek olarak görülüyor.

11 Aralık 2025 Perşembe

Next.js ile WebAuthn (Passkey) Entegrasyonu: Parolasız Giriş Adım Adım

Parolasız kimlik doğrulama, kullanıcı deneyimini iyileştirirken hesap güvenliğini artırmanın en pratik yolu haline geldi. WebAuthn ve Passkey teknolojileri sayesinde kullanıcılar artık SMS kodları veya karmaşık parolalar yerine cihazlarındaki biyometrik sensörlerle giriş yapabiliyor. Bu yazıda, Next.js üzerinde WebAuthn tabanlı Passkey entegrasyonunu adım adım anlatarak, hem teknik detayları hem de üretim ortamı için ipuçlarını paylaşacağım.

Kısaca özetlemek gerekirse, WebAuthn FIDO2 standardının bir parçasıdır ve tarayıcılar aracılığıyla donanımsal (Güvenli Anahtarlar, Touch ID, Windows Hello vb.) veya platform tabanlı kimlik doğrulayıcılarla anahtar çifti üretip doğrulamayı mümkün kılar. RP (Relying Party) ID, origin ve challenge mekanizmaları doğru kurgulandığında, hem phishing dirençli hem de kullanıcı dostu bir giriş deneyimi elde edersiniz.

Önkoşullar ve Mimari

Gerekenler: Node.js 18+, Next.js 13+ (App Router tercihen), HTTPS (yerelde self-signed veya localhost), ve bir sunucu tarafı doğrulama paketi. Toplulukta yaygın kullanılan kütüphanelerden biri @simplewebauthn. Akış şu şekilde işler: Sunucu, kayıt veya giriş için tek kullanımlık bir challenge üretir ve istemciye döner. İstemci, tarayıcıdaki navigator.credentials API’sini (veya sarmalayıcı kütüphane) çağırarak kimlik doğrulayıcıyla işlem yapar ve imzalı yanıtı sunucuya gönderir. Sunucu, public key ve imza doğrulamasıyla işlemi sonuçlandırır.

Kurulum

Yeni bir Next.js projesi oluşturarak başlayalım:

npx create-next-app@latest passkey-demo --typescript
cd passkey-demo
npm i @simplewebauthn/server @simplewebauthn/browser cookie uuid

Basit bir yapı için .env dosyanıza aşağıdaki değerleri ekleyin (yerel geliştirme için):

RP_ID=localhost
RP_NAME=Passkey Demo
ORIGIN=http://localhost:3000

Kayıt (Registration) Akışı

Kullanıcı bir Passkey oluşturmak istediğinde önce sunucudan registration options alır. Bu seçenekler, kimlik doğrulayıcıya hangi parametrelerle anahtar üretmesi gerektiğini söyler. Next.js App Router kullandığınızı varsayarak endpoint’leri şu şekilde düşünebilirsiniz:

// app/api/webauthn/registration/options/route.ts
import { generateRegistrationOptions } from '@simplewebauthn/server';
import { cookies } from 'next/headers';
import { v4 as uuid } from 'uuid';

export async function GET() {
  const userId = uuid(); // Demo için rastgele. Gerçekte gerçek kullanıcı ID'si olmalı.
  const opts = await generateRegistrationOptions({
    rpName: process.env.RP_NAME!,
    rpID: process.env.RP_ID!,
    userID: userId,
    userName: '[email protected]',
    attestationType: 'none',
    authenticatorSelection: {
      residentKey: 'preferred',
      userVerification: 'preferred',
    },
  });

  // Challenge'ı oturumda saklayın
  cookies().set('regChallenge', opts.challenge, { httpOnly: true });

  return new Response(JSON.stringify({ userId, options: opts }), { status: 200 });
}

İstemci tarafında, tarayıcı API’si ile uğraşmayı kolaylaştırmak için @simplewebauthn/browser paketini kullanabiliriz:

// app/register/page.tsx
'use client';
import { startRegistration } from '@simplewebauthn/browser';

export default function Register() {
  const onRegister = async () => {
    const res = await fetch('/api/webauthn/registration/options');
    const { userId, options } = await res.json();
    const attRes = await startRegistration(options);
    await fetch('/api/webauthn/registration/verify', {
      method: 'POST',
      body: JSON.stringify({ userId, attRes }),
    });
    alert('Passkey oluşturuldu!');
  };
  return <button onClick={onRegister}>Passkey Oluştur</button>;
}

Sunucu, istemciden gelen yanıtı doğrulamalıdır. Doğrulama sonunda public key’i ve ilgili metadata’yı kullanıcı profiline kalıcı olarak kaydedersiniz.

// app/api/webauthn/registration/verify/route.ts
import { verifyRegistrationResponse } from '@simplewebauthn/server';
import { cookies } from 'next/headers';

export async function POST(req: Request) {
  const { userId, attRes } = await req.json();
  const expectedChallenge = cookies().get('regChallenge')?.value;

  const verification = await verifyRegistrationResponse({
    response: attRes,
    expectedChallenge,
    expectedOrigin: process.env.ORIGIN!,
    expectedRPID: process.env.RP_ID!,
  });

  if (!verification.verified) return new Response('Doğrulanamadı', { status: 400 });

  // verification.registrationInfo'dan publicKey ve credentialID'yi alıp DB'ye kaydedin
  return new Response('OK', { status: 200 });
}

Giriş (Authentication) Akışı

Girişte benzer şekilde bir challenge üretip istemciye gönderirsiniz. Kullanıcı cihazındaki Passkey ile imzalanan yanıtı sunucu doğrular. Burada kullanıcıya ait kayıtlı credentialID’lerinizi ve public key’lerinizi DB’den çekmeniz gerekir.

// app/api/webauthn/authentication/options/route.ts
import { generateAuthenticationOptions } from '@simplewebauthn/server';
import { cookies } from 'next/headers';

export async function GET() {
  const opts = await generateAuthenticationOptions({
    rpID: process.env.RP_ID!,
    userVerification: 'preferred',
  });
  cookies().set('authChallenge', opts.challenge, { httpOnly: true });
  return new Response(JSON.stringify({ options: opts }), { status: 200 });
}
// app/login/page.tsx
'use client';
import { startAuthentication } from '@simplewebauthn/browser';

export default function Login() {
  const onLogin = async () => {
    const res = await fetch('/api/webauthn/authentication/options');
    const { options } = await res.json();
    const assertion = await startAuthentication(options);
    await fetch('/api/webauthn/authentication/verify', {
      method: 'POST',
      body: JSON.stringify({ assertion }),
    });
    alert('Giriş başarılı!');
  };
  return <button onClick={onLogin}>Passkey ile Giriş</button>;
}
// app/api/webauthn/authentication/verify/route.ts
import { verifyAuthenticationResponse } from '@simplewebauthn/server';
import { cookies } from 'next/headers';

// Not: Burada kullanıcıya ait credential'ları DB'den çekmelisiniz.
export async function POST(req: Request) {
  const { assertion } = await req.json();
  const expectedChallenge = cookies().get('authChallenge')?.value;

  const verification = await verifyAuthenticationResponse({
    response: assertion,
    expectedChallenge,
    expectedOrigin: process.env.ORIGIN!,
    expectedRPID: process.env.RP_ID!,
    authenticator: {
      credentialID: Buffer.from('...'), // DB'den
      credentialPublicKey: Buffer.from('...'), // DB'den
      counter: 0,
    },
  });

  if (!verification.verified) return new Response('Hatalı kimlik doğrulama', { status: 401 });
  return new Response('OK', { status: 200 });
}

Üretime Hazırlık: İpuçları ve En İyi Uygulamalar

- HTTPS zorunlu: WebAuthn, localhost harici kökenlerde güvenli bağlam ister. Prod ortamda gerçek sertifika kullanın.

- RP ID ve Origin uyumu: RP_ID alan adınızla, ORIGIN ise protokol ve host’la birebir eşleşmeli. Alt alan adları ve çoklu çevrelerde yanlış yapılandırma en yaygın hatadır.

- Challenge ve oturum: Challenge değerini kısa ömürlü ve kullanıcıya bağlı saklayın. CSRF ve yeniden oynatma saldırılarına karşı dikkatli olun.

- Kullanıcı deneyimi: Platform authenticator (cihaz içi) ve cross-platform (USB/NFC) anahtarları desteklediğinizden emin olun. Cihaz değişimlerinde çoklu Passkey veya hesap kurtarma akışları tasarlayın.

- Günlükleme ve ölçüm: Başarısız doğrulama nedenlerini (origin uyuşmuyor, RP ID yanlış, kullanıcı doğrulaması başarısız vb.) log’layın; destek taleplerini azaltır.

Sonuç

WebAuthn ve Passkey ile parolasız kimlik doğrulama, hem saldırı yüzeyini küçültür hem de kullanıcı memnuniyetini artırır. Next.js üzerinde @simplewebauthn ile kurulum oldukça hızlıdır: kayıt ve giriş için challenge kurgusu, doğru RP/Origin ayarı ve güvenli oturum yönetimi yapı taşlarını oluşturur. Bu mimariyi uygulayarak uygulamanızda modern, phishing dirençli ve yüksek dönüşüm oranına sahip bir giriş deneyimine geçiş yapabilirsiniz.

3 Aralık 2025 Çarşamba

Next.js ile Passkey (WebAuthn) Entegrasyonu: Parolasız Girişe Adım Adım Rehber

Giriş: Neden Passkey (WebAuthn)?

Parolalar hem kullanıcılar hem de geliştiriciler için baş ağrısı. Zayıf parolalar, kimlik avı, sızıntılar ve unutma problemi derken, güvenli ve sorunsuz bir deneyim için endüstri Passkey (FIDO2/WebAuthn) standartına hızla geçiyor. Passkey ile kullanıcılar biyometri (Face ID, Touch ID), donanım güvenlik anahtarı veya cihaz PIN’iyle güvenli ve parolasız giriş yapabiliyor. Bu rehberde, Next.js ve simplewebauthn kullanarak uçtan uca bir Passkey akışını nasıl kurabileceğinizi adım adım anlatıyorum.

Gereksinimler ve Kurulum

Başlamadan önce Node.js 18+, Next.js 13/14 App Router, bir veri tabanı (PostgreSQL veya MongoDB) ve HTTPS (localhost için Chrome’da güvenilir sertifika veya bir tünel aracı) gerekli. WebAuthn, origin ve rpID değerlerine duyarlıdır; yerel geliştirmede localhost ve üretimde gerçek alan adını kullanın. Kütüphaneler için npm i @simplewebauthn/server @simplewebauthn/browser komutunu çalıştırın.

Mimari: Kayıt ve Giriş Akışı

Passkey iki ana akıştan oluşur: Kayıt (Registration) ve Doğrulama (Authentication). Kayıtta sunucu bir challenge üretir, istemci bu veriyi cihazın güvenli donanımına kaydeder ve attestation verisini sunucuya geri yollar. Girişte ise sunucu yeni bir challenge üretir, istemci cihazı bunu imzalar ve imzalı assertion sunucuda doğrulanır. Tüm süreçte challenge değerini oturum (session, Redis) gibi geçici ve güvenli bir yerde tutmak önemlidir.

Sunucu Tarafı: Endpoints ve Doğrulama

Next.js App Router’da app/api altında iki çift endpoint tanımlayın: /register/generate ve /register/verify, /login/generate ve /login/verify. @simplewebauthn/server içindeki generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions ve verifyAuthenticationResponse yardımcıları işinizi hızlandırır.

Önemli alanlar: rpID alan adınız (ör. example.com), origin tam kök adresiniz (ör. https://example.com). Üretimde bunların sabit ve doğru olması gerekir. Kayıt doğrulandıktan sonra veritabanında şu alanları saklayın: kullanıcı kimliği, credential ID (base64url), publicKey, counter, transports, backupEligibility/backupState bilgileri. Girişte doğrulama sonrası karşılaştırma için counter değerini güncelleyerek yeniden oynatma saldırılarını engelleyin.

İstemci Tarafı: Tarayıcı API’leriyle Etkileşim

Tarayıcı tarafında @simplewebauthn/browser kütüphanesinin startRegistration ve startAuthentication fonksiyonlarını kullanın. Kayıt için önce /register/generate endpoint’inden seçenekleri alın, startRegistration çağrısını yapın ve sonucu /register/verify’e gönderin. Giriş için benzer şekilde /login/generate → startAuthentication → /login/verify akışını izleyin. Bu işlemler sırasında kullanıcı, cihazında biyometrik doğrulama veya güvenlik anahtarına dokunuş gibi bir etkileşimle süreci tamamlar.

Pratik İpuçları ve Sık Hatalar

- Origin/RP ID uyuşmazlığı: En yaygın hata budur. Geliştirmede https://localhost:3000 origin ile rpID=localhost kullanın. Üretimde https://alanadiniz.com ve rpID=alanadiniz.com şart.

- Challenge saklama: Challenge’ı oturumda tutmazsanız doğrulama başarısız olur. Kısa ömürlü bir store (Redis, Signed Cookie) güvenlidir.

- Discoverable credentials: Kullanıcının e-posta girmeden giriş yapabilmesi için resident keys (discoverable) açılabilir. Gizlilik ve UX dengesini iyi düşünün; bazı senaryolarda kullanıcı kimliğini yine de isteyebilirsiniz.

- Platform desteği: iOS/Android, Chrome/Safari/Edge yeni sürümlerde destekler iyi durumdadır; ancak eski cihazlarda güvenlik anahtarı (YubiKey) fallback’i planlayın.

Güvenlik ve Uyum Notları

WebAuthn, kimlik avını ciddi ölçüde azaltır; çünkü imza domain’e (origin) bağlıdır. Yine de bazı ek önlemler gerekir: her istek için CSRF koruması, üretimde HTTPS zorunluluğu, gelen yanıtlar için origin doğrulaması, güvenli cookie ayarları (HttpOnly, SameSite=Lax/Strict, Secure). Kullanıcının birden fazla cihazda passkey kullanabilmesi için hesap başına birden fazla credential kaydına izin verin ve kolay yönetim ekranları oluşturun.

Kurumsal ortamlarda enforce MFA ve politika tabanlı kayıt akışlarını düşünebilirsiniz. Ayrıca, backup/icloud passkey senkronizasyonu devredeyse, cihaz değişiminde kullanıcı deneyimi daha pürüzsüz olur. Bu arada, userVerification modunu required olarak ayarlamak, cihazda biyometrik/PIN doğrulamasını zorunlu kılarak güvenliği artırır.

Örnek Veri Modeli ve Loglama

Basit bir credential tablosu şu alanları içerebilir: id, userId, credentialId (unique), publicKey, counter, deviceType (platform/cross-platform), backupState, transports, createdAt, lastUsedAt. Her doğrulamada lastUsedAt ve counter değerlerini güncelleyin. Üretimde başarısız doğrulamalar için detaylı ancak kişisel veriyi ifşa etmeyen loglar tutun; PII saklamamaya özen gösterin.

Performans ve UX İyileştirmeleri

İlk boyamada kullanıcıya cihazın passkey desteklediğini hızlıca göstermek için PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() ile bir özellik kontrolü yapabilirsiniz. Desteklenmiyorsa alternatif girişi (OTP/Magic Link) otomatik önerin. SSR yerine istemci tarafında akışı tetikleyip, istekleri mutate eden bir data fetching yaklaşımı (SWR/React Query) ile ağ hatalarında kullanıcıya net geri bildirim sağlayın.

Sonuç

Passkey (WebAuthn) entegrasyonu, hem güvenliği hem de dönüşüm oranlarını artıran çağdaş bir yaklaşım. Next.js ve simplewebauthn ile kurulum nispeten hızlı; kritik nokta ise rpID/origin doğruluğu, challenge yönetimi ve credential saklama stratejisi. Bu rehberdeki adımları izleyerek parolasız deneyimi projenize ekleyebilir, kullanıcılarınıza modern ve güvenli bir giriş akışı sunabilirsiniz.

30 Kasım 2025 Pazar

Passkey (WebAuthn) ile Şifresiz Giriş: Next.js ve SimpleWebAuthn ile Uçtan Uca Kurulum

Passkey (WebAuthn) ile Şifresiz Giriş: Adım Adım Uygulama Rehberi

Parola yorgunluğu, kimlik avı ve SMS tabanlı doğrulamanın zayıflıkları derken, modern web uygulamalarında şifresiz giriş kaçınılmaz hale geldi. Passkey’ler, WebAuthn ve FIDO2 standartlarıyla desteklenen, biyometri veya cihaz kilidiyle korunan anahtar çiftlerine dayanır. Kullanıcı deneyimini hızlandırır, kimlik avına dayanıklıdır ve iCloud Anahtar Zinciri ile Google Password Manager gibi yöneticiler arasında senkronize olabilir. Bu yazıda, Next.js ve SimpleWebAuthn kütüphanesi ile uçtan uca bir passkey (WebAuthn) entegrasyonunu nasıl kuracağınızı adım adım anlatıyorum.

Neden Passkey?

Passkey, kullanıcının cihazında saklanan bir özel anahtar ile sunucunun sakladığı açık anahtarın eşleşmesine dayanır. Parola gönderilmez, dolayısıyla veri tabanı sızıntılarında parolaların çalınması gibi riskler ortadan kalkar. Kullanıcı cihazında biyometri (Face ID, Touch ID), donanım anahtarı (YubiKey) veya cihaz PIN’i ile doğrulama yapar. Tarayıcı ve platform desteği artık yaygınlaştı; Chrome, Safari ve Firefox, iOS/Android ve masaüstü işletim sistemlerinde kullanılabiliyor.

Mimari ve Gereksinimler

WebAuthn iki ana akış içerir: kayıt (registration) ve kimlik doğrulama (authentication). Her akışta sunucu benzersiz bir challenge üretir, istemci tarafında tarayıcı navigator.credentials API’si ile doğrulama cihazıyla imza atılır ve bu yanıt sunucuda doğrulanır. Üretimde HTTPS zorunludur ve RP ID (Relying Party ID) alan adınızla birebir eşleşmelidir (ör. rpID = example.com).

Teknoloji Seçimi

Örnek kurulum için Next.js 14 (Route Handlers veya App Router), sunucu tarafında @simplewebauthn/server, istemci tarafında @simplewebauthn/browser kullanılabilir. Veritabanı olarak Postgres veya bir KV deposu tercih edebilirsiniz. Saklanacak başlıca alanlar: kullanıcı kimliği, credentialID, publicKey, counter ve tercihen cihaz/metaveri.

Kayıt Akışı (Registration)

1) Kullanıcı e-posta/ID ile kayıt başlatır. Sunucu generateRegistrationOptions ile seçenekleri üretir, challenge’ı geçici olarak saklar ve istemciye döner. Örnek:

const opts = generateRegistrationOptions({ rpName: 'Uygulama Adı', rpID: 'example.com', userName: 'ali', userID: 'user-123', attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred', authenticatorAttachment: 'platform' } });

2) İstemci, tarayıcıda @simplewebauthn/browser yardımıyla kullanıcıdan biyometri izni ister ve kimlik bilgisi oluşturur:

const attResp = await startRegistration(opts);

3) Sunucu, verifyRegistrationResponse ile gelen cevabı doğrular; doğrulama başarılıysa credentialID, publicKey ve counter değerlerini kullanıcıyla ilişkilendirerek kalıcı olarak saklar.

Giriş Akışı (Authentication)

1) Kullanıcı giriş sayfasında e-posta/ID girer veya koşullu UI ile otomatik olarak öneri alır. Sunucu generateAuthenticationOptions ile yeni bir challenge üretir. İsteğe bağlı olarak yalnızca ilgili kullanıcının kayıtlı cihazlarını allowCredentials ile sınırlandırabilirsiniz.

2) İstemci tarafında çağrı yapılır:

const authResp = await startAuthentication(options);

3) Sunucu verifyAuthenticationResponse ile imzayı ve origin/rpID alanlarını doğrular, counter değerini günceller. Başarılıysa oturumu (cookie/JWT) kurar.

Koşullu UI (Conditional Mediation) ile Tek Tık Giriş

Chrome ve destekleyen tarayıcılarda, kullanıcı adı alanı odaktayken passkey önerilerini otomatik gösterebilirsiniz. Basitçe bir email input’unuz varken:

navigator.credentials.get({ publicKey: authOptions, mediation: 'conditional' });

Bunun çalışması için sayfanız HTTPS olmalı, autocomplete öznitelikleri doğru ayarlanmalı ve kullanıcı daha önce passkey kaydetmiş olmalıdır. Bu yöntem giriş sürtünmesini ciddi şekilde azaltır.

Güvenlik İpuçları ve En İyi Uygulamalar

- RP ID alan adınızla aynı olmalı; yerelde test ederken localhost kullanın veya geçerli bir sertifika ile alt alan adı hazırlayın.

- attestationType: 'none' çoğu senaryo için en iyisidir; gereksiz attestation verisi toplamayın.

- userVerification için 'required' yüksek güvenlikli sayfalar için uygundur (örn. ödeme, ayarlar). Genel girişte 'preferred' iyi bir dengedir.

- Kullanıcıların cihaz değiştirme/ekleme senaryoları için birden fazla passkey kaydına izin verin ve kurtarma seçenekleri (e-posta bağlantısı veya destek akışı) sunun.

- Rate limit, yeniden oynatma (replay) engelleme, kaynak (origin) ve challenge ömrünü doğrulamayı ihmal etmeyin.

Hata Ayıklama ve Test

- SecurityError: The operation is insecure genelde HTTPS veya RP ID uyuşmazlığını gösterir.

- NotAllowedError kullanıcı etkileşimi yokken veya işlemi iptal ettiğinde görülür; buton tıklamasıyla tetikleyin.

- Unknown authenticator veya eşleşmeyen credentialID için doğru kullanıcıyla ilişkilendirme yapıldığından emin olun.

- Tarayıcı konsolu ve about://webauthn (Chrome) test araçları ile sanal güvenlik anahtarı oluşturup akışları yerelde deneyebilirsiniz.

Performans ve UX

Passkey akışı minimal JSON veri alışverişine dayanır; SSR ve edge işleme ile gecikmeyi azaltabilirsiniz. Başarılı kayıt sonrası kullanıcının cihazı üzerinde parolayı da “kaldırmayı” önermek, geçişi hızlandırır. Kullanıcıya hangi cihazların kayıtlı olduğunu gösteren bir yönetim ekranı sunmak güveni artırır.

Sonuç

Passkey (WebAuthn) ile şifresiz giriş, güvenliği artırırken kullanıcı deneyimini de basitleştirir. Next.js ve SimpleWebAuthn ile kurulumu birkaç uç noktaya indirgenebilir: kayıt için seçenek üretme/doğrulama ve giriş için seçenek üretme/doğrulama. RP ID, HTTPS ve challenge yönetimi gibi kritik ayrıntılara dikkat ettiğiniz sürece, modern tarayıcılarda hızlı ve güvenli bir oturum altyapısı sağlayabilirsiniz.

25 Kasım 2025 Salı

Passkey ve WebAuthn ile Parolasız Giriş: Adım Adım Entegrasyon Rehberi (2025)

WebAuthn ve Passkey Nedir, Neden Önemli?

Parola yorgunluğu ve oltalama saldırıları, modern uygulamalar için en büyük güvenlik sorunlarından biri. WebAuthn (W3C standardı) ve FIDO2 ile gelen passkey yaklaşımı, kriptografik anahtarlar kullanarak parolasız ve oltalama dirençli oturum açmayı mümkün kılar. Kullanıcılar cihazlarındaki biyometrik doğrulama (Face ID, Touch ID, Windows Hello) veya güvenlik anahtarı (YubiKey) ile giriş yapar. 2025 itibarıyla Chrome, Safari ve Firefox, platformlar arası passkey senkronizasyonunu (iCloud Anahtarlık, Google Password Manager, 1Password) yaygın biçimde destekliyor.

Temel Kavramlar

Relying Party (RP) ID: Genellikle alan adınızdır (ör. example.com). HTTPS zorunludur ve RP ID ile domain eşleşmelidir.

Authenticator: Kimlik doğrulayıcı cihaz. Platform (cihazın kendi biyometri/TPM’i) veya roaming (USB/NFC/BLE güvenlik anahtarı) olabilir.

Attestation ve Assertion: Kayıt (credential üretimi) ve giriş (imzalı kanıt) aşamalarında tarayıcı ile sunucu arasında değiş tokuş edilen verilerin adlarıdır.

Discoverable Credentials (Resident Keys): Kullanıcının kullanıcı adı yazmadan sadece cihaz doğrulamasıyla oturum açmasına olanak tanır; passkey deneyiminin kalbidir.

Entegrasyon Mimarisi ve Akış

WebAuthn, istemci (tarayıcı) ve sunucu arasında iki ana akış tanımlar: (1) Kayıt ve (2) Giriş. Tipik uç noktalar: /webauthn/register/options (sunucu challenge üretir), /webauthn/register/verify (sunucu attestation doğrular), /webauthn/login/options (sunucu challenge üretir), /webauthn/login/verify (sunucu assertion doğrular). Sunucu tarafında kullanıcıya ait credentialID, publicKey (COSE formatında), signCount, transports ve isteğe bağlı userHandle kalıcı olarak saklanır.

Gereksinimler ve Dikkat Edilecekler

- Uygulamanız HTTPS üzerinde çalışmalı. Lokal geliştirme için localhost istisnası var, ancak üretimde sertifika zorunlu.
- RP ID, alt alan adları ile farklılık gösterebilir. Örneğin app.example.com için RP ID’yi example.com seçerseniz, alt alanlar arasında passkey paylaşımı kolaylaşır.
- Sunucuda doğru algoritma setini (ES256 gibi) destekleyin.
- Origin ve RP ID mutlak doğrulanmalı; aksi halde güvenlik modeli bozulur.
- signCount (veya signature counter) replay tespitinde kullanılmalıdır.

Uygulama Örneği: Sunucu ve İstemci

Sunucu teknolojisi fark etmeksizin yaklaşım aynıdır. Node.js için @simplewebauthn/server, tarayıcı tarafı için @simplewebauthn/browser; Java için webauthn4j; .NET için Fido2NetLib yaygın kütüphanelerdir.

Kayıt adımları: 1) Kullanıcı oturum açmış veya e-posta doğrulamış olmalı. 2) Sunucu challenge üretir, rp (name, id), user (id, name), pubKeyCredParams, authenticatorSelection (residentKey=required, userVerification=preferred/required) gibi alanlarla tarayıcıya döner. 3) Tarayıcı navigator.credentials.create({ publicKey: ... }) çağırır. 4) Tarayıcıdan dönen attestation, sunucuda doğrulanır; geçerliyse publicKey kaydedilir.

Giriş adımları: 1) Sunucu challenge üretir ve allowCredentials (istemciye bağlı ise opsiyonel) ile döner. 2) Tarayıcı navigator.credentials.get({ publicKey: ... }) çağırır. 3) Dönen assertion, imza ve authenticatorData sunucuda doğrulanır; signCount güncellenir ve oturum açılır.

Passkey UX İpuçları ve Conditional UI

Modern tarayıcılarda “Conditional UI” desteğiyle, kullanıcı adı alanı odaklanmadan dahi passkey önerisi açılabilir. Tarayıcı tarafında mediation: "conditional" kullanımı, şifre doldurma ile tutarlı bir deneyim sunar. Özellikle mobilde autofill entegrasyonu dönüşüm oranlarını artırır. “Kullanıcı adı olmadan giriş” senaryosu için “discoverable credentials” etkin olmalıdır.

Cihazlar Arası Senkronizasyon ve Kurtarma

Passkey’ler iCloud Keychain, Google Password Manager veya destekleyen parola kasalarında şifrelenmiş biçimde senkronize olabilir. Kullanıcılara en az bir roaming güvenlik anahtarı veya alternatif kurtarma yöntemi önerin. SMS/e-posta yedekleri zorunlu olmamalı; mümkünse TOTP veya ek bir passkey kaydı sağlayın.

Güvenlik ve Uyum

- Attestation politikanızı belirleyin: “none” çoğu tüketici uygulaması için yeterli, kurumsal ortamda AAGUID bazlı kısıtlama gerekebilir.
- Phishing dirençli olması, RP ID sabitlemesi ve kullanıcı doğrulaması (UV) ile sağlanır.
- Rate limiting, origin checking ve replay protection uygulayın.
- Log’larda özel anahtar yer almaz; yalnızca publicKey ve metadata saklanır.

Test, Hata Ayıklama ve Yayına Alma

Geliştirme sürecinde Chrome’un Virtual Authenticator panelini (chrome://webauthn) kullanarak farklı cihaz senaryolarını simüle edebilirsiniz. Staging ortamında gerçek cihazlarla (iOS Safari, Android Chrome, Windows Hello) çapraz test yapın. CDN veya ters proxy arkasında origin/RP ID uyuşmazlıklarına dikkat edin. Son aşamada parola ile hibrit oturum açma bir süre daha açık tutulabilir; ardından parolayı kademeli kaldırma stratejisi izlenebilir.

Sonuç

WebAuthn ve passkey, kullanıcı deneyimini iyileştirirken güvenliği ciddi biçimde artırır. Doğru RP ID, sıkı origin doğrulaması, güvenilir kütüphaneler ve iyi bir kurtarma politikası ile entegrasyon sorunsuz ilerler. Bugün küçük bir pilot başlatıp kullanıcılarınızın en çok kullandığı platformlarda test ederek geçişi adım adım hızlandırabilirsiniz.

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 Kasım 2025 Çarşamba

Next.js ile Passkey (WebAuthn/FIDO2) Entegrasyonu: Şifresiz Giriş Nasıl Eklenir?

Özet: Passkey (WebAuthn/FIDO2) ile şifresiz kimlik doğrulama, kimlik avına dayanıklı ve kullanıcı deneyimi yüksek modern bir giriş yöntemidir. Bu rehberde, Next.js üzerinde passkey kaydı ve giriş akışını adım adım nasıl kuracağınızı anlatıyorum. Amaç, pratik bir örnekle üretime yakın bir mimari oluşturmak ve SEO dostu bir içerikle temel kavramları sade şekilde aktarmaktır.

Passkey Nedir ve Neden Önemli?

Passkey, kullanıcıların parolasız şekilde oturum açmasını sağlayan, cihazın güvenli donanım modülü veya güvenli alanında saklanan FIDO2/WebAuthn kimlik bilgilerine dayanan bir yöntemdir. Phishing’e karşı dirençlidir, ikinci faktör ihtiyacını ortadan kaldırabilir ve kullanıcı tarafında dokunma/yüz tanıma gibi biyometrik doğrulamalarla çalışır. iOS, Android, Windows ve macOS’ta platform desteği geniştir.

Gereksinimler

- Next.js 13/14 (App Router veya Pages Router)
- Node.js 18+
- HTTPS (geliştirmede localhost istisnası vardır)
- Sunucu tarafında oturum (session) veya kısa süreli challenge saklama mekanizması
- Bir veritabanı (ör. PostgreSQL, SQLite veya MongoDB)

Mimari ve Terimler

RP ID (Relying Party ID): Genellikle alan adınızın eTLD+1 formatı (ör. example.com). Localhost için rpID: localhost kullanılabilir.
Challenge: Sunucuda üretilen tek seferlik rastgele dize; hem kayıt hem girişte imzalanır ve doğrulanır.
Credential: Kullanıcıya ait public key, credentialId, counter ve transports gibi bilgilerden oluşur.

Kurulum

Next.js projesi oluşturun ve gerekli paketleri ekleyin:

npx create-next-app passkey-app
cd passkey-app
npm i @simplewebauthn/server @simplewebauthn/browser base64url

Veritabanında şu alanlara ihtiyacınız olacak: userId, credentialId (Buffer/Base64URL), publicKey (PEM/COSE), counter (number), transports (string[]). Örnek bir tablo/collection şeması oluşturun.

Kayıt (Registration) Akışı

1) Sunucu tarafında kayıt seçeneklerini üretin ve challenge’ı oturumda saklayın:

// app/api/webauthn/register-options/route.ts
import { generateRegistrationOptions } from '@simplewebauthn/server';

export async function GET() {
  const rpID = process.env.RP_ID || 'localhost';
  const user = { id: 'u_123', name: '[email protected]', displayName: 'Ali' };

  const options = await generateRegistrationOptions({
    rpName: 'Passkey Demo',
    rpID,
    userID: user.id,
    userName: user.name,
    userDisplayName: user.displayName,
    attestationType: 'none',
    authenticatorSelection: {
      residentKey: 'preferred',
      userVerification: 'required',
      authenticatorAttachment: 'platform',
    },
  });

  // TODO: session.set('currentChallenge', options.challenge)
  return Response.json(options);
}

2) İstemci tarafında kullanıcının cihazında passkey oluşturun:

// app/register/page.tsx
'use client';
import { startRegistration } from '@simplewebauthn/browser';

export default function Register() {
  const onRegister = async () => {
    const opts = await fetch('/api/webauthn/register-options').then(r => r.json());
    const attRes = await startRegistration(opts);
    await fetch('/api/webauthn/register-verify', {
      method: 'POST',
      body: JSON.stringify(attRes),
    });
  };
  return <button onClick={onRegister}>Passkey Oluştur</button>;
}

3) Sunucu tarafında yanıtı doğrulayın ve kimlik bilgilerini veritabanına kaydedin:

// app/api/webauthn/register-verify/route.ts
import { verifyRegistrationResponse } from '@simplewebauthn/server';

export async function POST(req: Request) {
  const body = await req.json();
  const expectedChallenge = /* session.get('currentChallenge') */ '';
  const rpID = process.env.RP_ID || 'localhost';
  const origin = process.env.ORIGIN || 'http://localhost:3000';

  const { verified, registrationInfo } = await verifyRegistrationResponse({
    expectedRPID: rpID,
    expectedOrigin: origin,
    expectedChallenge,
    response: body,
  });

  if (verified && registrationInfo) {
    const { credentialPublicKey, credentialID, counter, credentialDeviceType, credentialBackedUp } = registrationInfo;
    // TODO: DB'ye userId ile birlikte credentialID, credentialPublicKey, counter, transports kaydedin
  }
  return Response.json({ verified });
}

Giriş (Authentication) Akışı

1) Sunucuda kullanıcıya ait credentialId listesini kullanarak seçenek üretin:

// app/api/webauthn/auth-options/route.ts
import { generateAuthenticationOptions } from '@simplewebauthn/server';

export async function GET() {
  const rpID = process.env.RP_ID || 'localhost';
  const userCreds = [ /* DB'den credentialId'ler */ ];

  const options = await generateAuthenticationOptions({
    rpID,
    userVerification: 'required',
    allowCredentials: userCreds.map(c => ({
      id: c.credentialId,
      type: 'public-key',
      transports: c.transports || ['internal'],
    })),
  });

  // TODO: session.set('currentChallenge', options.challenge)
  return Response.json(options);
}

2) İstemci tarafında kimlik doğrulaması başlatın ve yanıtı sunucuya gönderin:

// app/login/page.tsx
'use client';
import { startAuthentication } from '@simplewebauthn/browser';

export default function Login() {
  const onLogin = async () => {
    const opts = await fetch('/api/webauthn/auth-options').then(r => r.json());
    const assertion = await startAuthentication(opts);
    const res = await fetch('/api/webauthn/auth-verify', {
      method: 'POST',
      body: JSON.stringify(assertion),
    });
    const { verified } = await res.json();
    if (verified) alert('Giriş başarılı');
  };
  return <button onClick={onLogin}>Passkey ile Giriş</button>;
}

3) Sunucuda doğrulama yapın ve counter değerini güncelleyin:

// app/api/webauthn/auth-verify/route.ts
import { verifyAuthenticationResponse } from '@simplewebauthn/server';

export async function POST(req: Request) {
  const body = await req.json();
  const expectedChallenge = /* session.get('currentChallenge') */ '';
  const rpID = process.env.RP_ID || 'localhost';
  const origin = process.env.ORIGIN || 'http://localhost:3000';

  // TODO: DB'den credentialId'ye göre publicKey ve counter'ı çekin
  const dbCred = {/* ... */};

  const { verified, authenticationInfo } = await verifyAuthenticationResponse({
    expectedRPID: rpID,
    expectedOrigin: origin,
    expectedChallenge,
    response: body,
    authenticator: {
      credentialID: dbCred.credentialId,
      credentialPublicKey: dbCred.publicKey,
      counter: dbCred.counter,
      transports: dbCred.transports,
    },
  });

  if (verified) {
    // TODO: DB'de counter'ı authenticationInfo.newCounter ile güncelleyin
    // TODO: uygulama oturumunu başlatın
  }
  return Response.json({ verified });
}

Koşullu UI ve Kullanılabilirlik İpuçları

- Chrome’da “conditional UI” ile giriş formu göstermeden tarayıcı otomatik passkey önerisi sunabilir. startAuthentication çağrısını buna göre optimize edin.
- Kullanıcıya “Aygıtınızda passkey saklanacak” gibi kısa, anlaşılır mesajlarla rehberlik edin.
- Eşitleme: iCloud Keychain veya Google Password Manager ile passkey’ler cihazlar arasında senkronize olabilir.

Güvenlik ve Üretim Notları

- Her zaman HTTPS kullanın; origin ve rpID tutarlılığı hayati önem taşır.
- Challenge değerlerini kısa ömürlü ve tek kullanımlık tutun.
- Çoklu cihaz senaryolarında bir kullanıcıya birden fazla credential kaydına izin verin.
- Hata Yönetimi: NotAllowedError genelde kullanıcı iptali veya zaman aşımından kaynaklanır; kullanıcı dostu hata mesajları gösterin.

Sonuç olarak, Next.js üzerinde passkey entegrasyonu birkaç API uç noktası ve doğru challenge yönetimiyle oldukça akıcı bir hale geliyor. Parolaları terk etmek hem güvenliği artırır hem de dönüşüm oranlarını yükseltir. Üretime alırken oturum süreleri, cihaz yönetimi ve kurtarma seçeneklerini (ör. e-posta magic link) birlikte kurgulamanızı öneririm.

8 Kasım 2025 Cumartesi

WebAuthn Passkey Entegrasyonu: Parolasız Giriş Nasıl Eklenir? (Adım Adım Rehber)

Passkey Nedir ve Neden Önemli?

Parolalar hem kullanıcılar hem de geliştiriciler için sorunlu: Zayıf şifreler, phishing saldırıları ve tekrar kullanım derken, güvenlik açıkları kaçınılmaz hale geliyor. Passkey (FIDO2/WebAuthn tabanlı parolasız kimlik doğrulama) bu tabloyu değiştiriyor. Kullanıcılar cihazlarının biyometrik doğrulamasıyla (Face ID, Touch ID, Windows Hello vb.) giriş yapıyor; sunucu tarafında ise yalnızca herkese açık anahtar saklanıyor. Bu yaklaşım phishing’e dirençli, kullanıcı deneyimi açısından zahmetsiz ve uzun vadede bakım maliyetini düşürüyor.

Mimari: Kısa Bir Genel Bakış

WebAuthn, iki ana akışa dayanır: kayıt (registration) ve giriş (authentication). Kayıt akışında sunucu, istemciye bir challenge ve parametreler gönderir; tarayıcı navigator.credentials.create() ile cihaz üzerinde bir anahtar çifti üretir ve herkese açık anahtarı sunucuya geri yollar. Giriş akışında ise sunucu challenge üretir, istemci navigator.credentials.get() ile imza alır ve sunucu bunu doğrular. Tüm süreçte parolayı ne ilettiğinizi ne de sakladığınızı düşünmeniz gerekmez.

Gereksinimler ve Dikkat Edilmesi Gerekenler

- Uygulamanızın HTTPS üzerinde çalışması gerekir (localhost hariç).
- RP ID alanı, genellikle alan adınızın köküdür (ör. example.com). Alt alanlar için doğru RP ID seçimi önemlidir.
- Tarayıcı ve platform desteği oldukça geniştir; yine de eski cihazları hedefliyorsanız geriye uygun bir strateji belirleyin.
- Passkey’lerin cihazlar arası senkronizasyonu (ör. iCloud Anahtar Zinciri, Google Password Manager) kullanıcı deneyimini iyileştirir, ancak kurumsal ortamlarda harici güven anahtarlarını da (security key) desteklemek isteyebilirsiniz.

Kayıt (Registration) Akışı: Adım Adım

1) Kullanıcı yeni hesap oluşturmak veya hesabına passkey eklemek istediğinde, sunucu bir challenge üretir ve publicKeyCredentialCreationOptions nesnesini oluşturur. Bu nesnede rp (adı ve id), user (id, name, displayName), pubKeyCredParams (COSE algoritmaları), authenticatorSelection (ör. residentKey, userVerification), timeout ve gerekiyorsa attestation alanları yer alır.

2) İstemci tarafında tarayıcıya navigator.credentials.create({ publicKey }) çağrısı yaptırılır. Kullanıcı biyometrik doğrulama ile onaylar. Tarayıcı size id, rawId, response.attestationObject ve response.clientDataJSON döndürür.

3) Sunucu bu verileri doğrular: clientDataJSON içindeki challenge, type ve origin kontrol edilir; attestationObject içinden sertifika zinciri ve anahtar bilgisi çıkarılır. Sonuçta kullanıcı kaydı için credential ID, public key ve signCount veritabanına kaydedilir.

4) Attestation politikanızı belirleyin: Çoğu tüketici uygulaması için none yeterlidir. Düzenlemeye tabi sektörlerde (finans, sağlık) cihaz kanıtı (attestation) şartları farklı olabilir.

Giriş (Authentication) Akışı: Adım Adım

1) Kullanıcı “Giriş Yap” dediğinde sunucu bir challenge üretir ve publicKeyCredentialRequestOptions oluşturur. Bu nesnede challenge, timeout, rpId ve varsa allowCredentials bulunur.

2) İstemci navigator.credentials.get({ publicKey }) çağrısı yapar. Tarayıcı kullanıcı doğrulamasını ister ve size id, rawId, response.authenticatorData, response.clientDataJSON, response.signature ve mümkünse userHandle döndürür.

3) Sunucu doğrulama yapar: clientDataJSON içindeki challenge ve origin kontrol edilir; authenticatorData içinden RP ID hash, bayraklar ve sayaç (signCount) okunur. signature, veritabanına kaydettiğiniz herkese açık anahtarla doğrulanır. Sayaç ileri gitmiyorsa tekrar kullanım şüphesiyle oturumu reddedin veya riske göre ek doğrulama isteyin.

Discoverable Credentials ve Kullanıcı Deneyimi

Passkey’lerin en güçlü yanlarından biri, discoverable credentials desteğidir. Bu sayede kullanıcı, e-posta veya kullanıcı adı girmeden doğrudan cihazındaki passkey ile giriş yapabilir. authenticatorSelection.residentKey = "required" ve userVerification = "required" ayarlarıyla modern bir “tek dokunuşla giriş” deneyimi sağlayabilirsiniz.

Güvenlik ve Uyum İpuçları

- Her istek için tek kullanımlık random challenge üretin ve kısa süreliğine geçerli kılın.
- RP ID ve origin eşleşmesini sıkı tutun; üretim ve test ortamlarını karıştırmayın.
- Rate limiting ve risk tabanlı kontroller (IP, cihaz parmak izi, olağandışı saat dilimi) ekleyin.
- Kullanıcının passkey kaybına karşı yedek faktör (TOTP, e-posta onayı, güvenlik anahtarı) sunun; ancak bu faktörleri de phishing’e dayanıklı hale getirmeyi hedefleyin.
- Veritabanınızda publicKey, credentialId, signCount, transports, aaguid gibi alanları saklayın; ileride politika kararları için faydalıdır.

Test, Hata Ayıklama ve Ölçüm

Geliştirme sırasında tarayıcının geliştirici araçlarındaki WebAuthn panelini kullanın; sanal güvenlik anahtarlarıyla senaryoları çoğaltabilirsiniz. Kayıt ve giriş akışlarında challenge ömrü, origin eşleşmesi ve base64url dönüşümleri en sık hata yapılan noktalardır. Üretimde ise başarısızlık oranı, adım terk ve cihaz/OS dağılımı gibi metrikleri izleyip sürtünme noktalarını azaltın.

Sonuç: Daha Güvenli ve Daha Hızlı Giriş

Passkey, hem güvenliği hem de kullanıcı deneyimini aynı anda iyileştiren nadir teknolojilerden biri. Parola sıfırlama süreçleri, bot saldırıları ve sahte giriş sayfalarıyla uğraşmak yerine, kökünden daha sağlam bir mimariye geçiyorsunuz. Küçük bir pilot kuvvetle başlayıp kullanıcı kitlenizin cihaz dağılımını ölçün; ardından parolasız girişe kademeli geçiş stratejisi belirleyin. Doğru uygulandığında, yardım masası yükü azalır, giriş süreleri kısalır ve dönüşüm oranları gözle görülür biçimde artar.

7 Kasım 2025 Cuma

Passkeys (WebAuthn) ile Şifresiz Giriş: Next.js ve Node.js Üzerinde Adım Adım

Passkeys nedir ve neden şimdi?

Şifre yorgunluğu, kimlik avı ve parola sızıntıları artık sıradan hale geldi. Passkeys, yani WebAuthn ve FIDO2 tabanlı şifresiz kimlik doğrulama, bu sorunları kökten çözen modern bir yaklaşım. Apple, Google ve Microsoft ekosistemlerinde yerleşik çalışırken, kullanıcılar cihazlarının biyometrisini (Face ID, Touch ID, Windows Hello) veya güvenlik anahtarlarını kullanarak güvenli ve tek dokunuşla giriş yapabiliyor. Bu yazıda, Next.js ve Node.js üzerinde Passkeys entegrasyonunu adım adım anlatacağım.

Mimari ve çalışma mantığı

Passkeys, asimetrik kriptoya dayanır: cihaz üzerinde üretilen bir özel anahtar ve sunucuda saklanan açık anahtar. Kayıt (registration) sırasında cihaz, alan adınıza (RP ID) bağlı bir anahtar çifti üretir ve attestation ile birlikte sunucuya gönderir. Giriş (authentication) aşamasında ise sunucu bir challenge üretir; cihaz bu challenge’ı özel anahtarla imzalar ve sunucu açık anahtarla doğrular. Şifre yok, gizli veri sunucuya taşınmıyor ve kimlik avına dayanıklı bir akış elde ediliyor.

Önkoşullar

1) Üretimde mutlaka HTTPS kullanın.
2) RP ID, alan adınızla birebir uyumlu olmalı (örn. example.com).
3) Tarayıcı desteği: Modern Chrome, Safari, Firefox sürümleri WebAuthn destekliyor.
4) En az bir authenticator (platform: telefon/bilgisayar; roaming: YubiKey).
5) Node.js 18+ ve Next.js 13+ önerilir.
6) Sunucuda rastgele ve tekil challenge üretecek bir mekanizma (ör. crypto.randomBytes) ve doğrulama için bir kütüphane (örn. @simplewebauthn/server) kullanın.

Kayıt (Registration) akışı

1. Kullanıcıyı başlatın: Kullanıcı e-postası veya kullanıcı adıyla kayıt talebi gönderir.
2. Sunucu challenge üretir: RP bilgileriyle birlikte options döner: rp.id, rp.name, user.id (stabil benzersiz ID), user.name, pubKeyCredParams, attestation, timeout.
3. İstemci oluşturma isteği: Tarayıcıda navigator.credentials.create({ publicKey: options }) çağrısı yapılır.
4. Sunucu doğrular: İstemciden gelen attestation yanıtı (id, rawId, response.attestationObject, clientDataJSON) sunucuda doğrulanır. Başarılıysa credentialId, publicKey, signCount ve kullanıcıyla ilişkilendirilerek veritabanına kaydedilir.

Örnek sunucu mantığı (özet):
// /api/webauthn/register/options
const options = generateRegistrationOptions({ rpID, rpName, userID, userName });
storeChallenge(userID, options.challenge);
return options;

// /api/webauthn/register/verify
const verification = verifyRegistrationResponse({ response, expectedRPID: rpID, expectedOrigin, expectedChallenge });
if (verification.verified) saveCredential(userID, verification.registrationInfo);

Giriş (Authentication) akışı

1. Sunucu assertion options üretir: registered credentialId’leri, rpID ve challenge içeren options döndürür.
2. İstemci doğrulama isteği: navigator.credentials.get({ publicKey: options }) çağrısı çalışır. Kullanıcı biyometri/güvenlik anahtarıyla onay verir.
3. Sunucu doğrular: İmza (signature), authenticatorData ve clientDataJSON kullanılarak open-key üzerinde imza doğrulanır.
4. Sayaç kontrolü: authenticator signCount önceki değerden küçükse tekrar saldırısı şüphesi doğar; oturumu reddedin. Başarılıysa kullanıcıyı oturum açmış sayın.

Örnek sunucu mantığı (özet):
// /api/webauthn/login/options
const options = generateAuthenticationOptions({ rpID, allowCredentials: userCredIds });
storeChallenge(userID, options.challenge);
return options;

// /api/webauthn/login/verify
const verification = verifyAuthenticationResponse({ response, expectedRPID: rpID, expectedOrigin, expectedChallenge, authenticator });
if (verification.verified) updateSignCount(authenticator, verification.authenticationInfo.newCounter);

Next.js tarafında istemci akışı

Next.js App Router ile, client component içinde WebAuthn çağrılarını başlatabilirsiniz. Kayıtta: sunucudan options’ı fetch edin, navigator.credentials.create ile yanıtı alın ve verify endpoint’ine POST edin. Girişte: benzer şekilde options alıp navigator.credentials.get çağırın. Hata yönetimi için kullanıcıya net mesajlar gösterin (ör. “Bu cihazda passkey yok, lütfen yeni bir passkey oluşturun”).

Güvenlik ve en iyi uygulamalar

- Origin ve RP ID uyuşmazlıklarını önleyin; staging/prod için ayrı ayar kullanın.
- Challenge değerleri kriptografik rastgele ve tek kullanımlık olmalı.
- Attestation politikasını belirleyin: “none”, “indirect” veya belirli üretici politikaları.
- Çoklu cihaz desteği için bir kullanıcıya birden fazla credential bağlayın.
- Yedekleme/kurtarma senaryosu için platform passkey + güvenlik anahtarı kombinasyonunu teşvik edin.
- Oturum çerezi/Token için HttpOnly, Secure ve SameSite ayarlarını doğru yapılandırın.

Kullanıcı deneyimi ipuçları

- Conditional UI (Chrome) ile otomatik Passkey doldurma akışını etkinleştirin; login sayfasında kullanıcı adı sormadan hızlı giriş sunar.
- Parolayı gizli seçenek olarak sunun; öncelik Passkey akışında olsun.
- Kullanıcıya “Bu cihazda passkey oluştur” veya “Farklı cihazla tara” gibi net eylemler verin.
- Mobilde QR tabanlı çapraz cihaz akışlarını destekleyin; tarayıcılar yerleşik olarak buna hazır.

Performans ve gözlemleme

WebAuthn işlemleri genellikle milisaniyeler içinde biter, ancak ağ gecikmesi ve attestation doğrulaması süresini izleyin. Kayıt ve giriş sürelerini ölçmek için basit metrikler (options fetch süresi, create/get süresi, verify süresi) tutun. Başarısızlık oranlarını izlemek, cihaz/OS bazlı hataları hızlıca ayrıştırmanızı sağlar.

Sonuç

Passkeys, güvenliği artırırken kullanıcı deneyimini de iyileştirir. Next.js ve Node.js üzerinde WebAuthn/FIDO2 ile kuracağınız şifresiz giriş çözümü, kimlik avına dirençli, hızlı ve modern bir oturum açma deneyimi sunar. Yukarıdaki mimari ve akışla kısa sürede üretim seviyesinde bir entegrasyon geliştirebilir, parolalara veda ederken dönüşüm oranlarınızı artırabilirsiniz.