1 Kasım 2025 Cumartesi

Passkey (WebAuthn) ile Parolasız Giriş Nasıl Eklenir? Next.js ve SimpleWebAuthn ile Adım Adım

Passkey nedir ve neden şimdi?

Parolalar artık güvenliğin en zayıf halkası. Passkey, FIDO2 ve WebAuthn standartları ile çalışan, kimlik doğrulamayı cihazınızdaki güvenli donanım modüllerine (Secure Enclave, TPM) emanet eden parolasız bir giriş yöntemidir. Kimlik avına dayanıklıdır, şifre sızmalarından etkilenmez ve iCloud Anahtar Zinciri, Google Parola Yöneticisi ve Microsoft hesabı ile senkronize olabilir. Bu yazıda, modern bir React çerçevesi olan Next.js üzerinde SimpleWebAuthn kullanarak passkey entegrasyonunu adım adım kuracağız.

Mimariyi hızlıca anlayalım

WebAuthn iki temel akıştan oluşur: Kayıt (Registration) ve Giriş (Authentication). Sunucu “relying party” olarak bir challenge üretir, tarayıcı ve cihazınızdaki kimlik doğrulama modülü bu challenge’ı özel anahtar ile imzalar, sunucu da daha önce kaydedilen genel anahtar ile imzayı doğrular. Kritik parametreler: rpId (alan adınız), origin (https kökeniniz), user.id (kalıcı benzersiz kimlik), counter (replay saldırılarına karşı sayaç) ve userVerification (biyometrik/PIN doğrulaması). Hepsi doğru ayarlanmadığında tarayıcı güvenlik nedeniyle işlemi reddeder.

Gerekenler ve kurulum

Başlamak için Node.js 18+ ve Next.js 13+ önerilir. Örneklerde App Router kullanılacaktır. Projeyi oluşturmak için: npx create-next-app@latest passkey-demo. Ardından gerekli kütüphaneler: npm i @simplewebauthn/server @simplewebauthn/browser cookie. Basitlik için oturumları cookie ile yöneteceğiz; gerçek projede JWT veya session store tercih edebilirsiniz.

Kayıt (registration) akışı

1) Sunucu tarafı seçenek üretimi: Kullanıcı yeni bir passkey oluşturmak istediğinde generateRegistrationOptions ile istemciye seçenek döndürün. Örnek ayarlar: rpName: 'Örnek Uygulama', rpID: 'alanadiniz.com', userID: 'kalici-uuid', userName: '[email protected]', attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' }. Bu adımda kullanıcıya bir challenge ve uyumlu parametreler verilir.

2) İstemci tarafı oluşturma: Tarayıcıda startRegistration(options) çağrılır ve kullanıcı cihazındaki biyometrik/PIN doğrulaması tetiklenir. İşlem başarılıysa dönen attestationResponse’ı backend’e gönderirsiniz.

3) Doğrulama ve kaydetme: Sunucuda verifyRegistrationResponse ile origin ve rpID doğrulanır. Başarılıysa veritabanına şu alanları kaydedin: credentialId (Base64URL), publicKey, counter, userId, transports, tercihen aaguid ve device type. Bu kayıt, o kullanıcının passkey’inin “kamu anahtarını” temsil eder.

Giriş (authentication) akışı

1) Seçenek üretimi: generateAuthenticationOptions ile istemciye yeni bir challenge gönderin. Eğer sadece belirli kayıtlı kimlik bilgilerine izin vermek isterseniz allowCredentials içinde credentialId’leri gönderin. Parolasız deneyim için discoverable credentials (residentKey) tercih edilir.

2) İstemci doğrulaması: Tarayıcıda startAuthentication(options) çağrılır. Kullanıcı biyometrik/PIN ile onaylar, ortaya çıkan assertionResponse sunucuya gönderilir.

3) Sunucu doğrulaması: verifyAuthenticationResponse ile imza doğrulanır; challenge, origin, rpId ve counter kontrol edilir. Sayaç değeri yükseldiyse veritabanındaki counter güncellenir. Başarılıysa kullanıcıyı oturum açmış sayıp güvenli bir Set-Cookie ile session başlatın.

Üretim için kritik güvenlik ayarları

- HTTPS zorunludur. WebAuthn yalnızca güvenli kökenlerde çalışır (localhost hariç). Cloudflare, Vercel veya kendi Nginx ters proxy’nizle TLS sağlayın.

- rpID tam alan adınız olmalı ve origin ile uyumlu olmalı. Örn. app.ornek.com kullanıyorsanız http:// değil https://app.ornek.com üzerinden test edin.

- userVerification’ı en az preferred, kritik işlemlerde required yapın; böylece biyometri/PIN doğrulaması zorunlu olur.

- Attestation çoğu senaryoda none kalabilir. Cihaz sınıfı kontrolü istiyorsanız indirect veya direct kullanabilir, gizlilik etkilerini değerlendirmelisiniz.

- Orta katmanda rate limiting, CSRF koruması ve replay önlemleri (tek kullanımlık challenge, kısa süreli TTL) uygulayın.

Tarayıcı ve cihaz uyumluluğu

Güncel Chrome, Safari ve Edge sürümleri passkey’i destekliyor. iOS ve Android cihazlarda platform authenticator ile sorunsuz çalışır. Masaüstünde “telefonla doğrula” akışı (QR/BT) mümkün. Kullanıcılara “fiziksel güvenlik anahtarı” (YubiKey) ile ek kayıt yaptırmak da kurtarma planı olarak önerilir.

Sık karşılaşılan hatalar

NotAllowedError: Kullanıcı etkileşimi (click) yoksa veya işlem zaman aşımına uğradıysa görülür. İşlemleri buton tıklamasıyla başlatın ve timeout değerini 60–120 sn yapın.

InvalidStateError: Aynı cihazda aynı kullanıcı için tekrar kayıt deneniyorsa oluşabilir. Kayıt öncesi kullanıcıya mevcut passkey’i kaldırma veya yeni cihaz olarak ekleme seçenekleri sunun.

RP ID hatası: “The RP ID is not a registrable domain” mesajı alıyorsanız muhtemelen localhost dışı http kullanıyorsunuzdur. Her zaman https kullanın ve alan adınızın kökeni ile rpID’yi eşleştirin.

Sonuç ve öneriler

Passkey entegrasyonu hem güvenliği hem de dönüşümü artırır: kullanıcılar parolaları hatırlamak zorunda kalmaz, giriş süresi kısalır. Next.js ve SimpleWebAuthn ikilisiyle temel kurulum birkaç saat içinde tamamlanabilir. Üretimde çoklu cihaz desteği, kurtarma seçenekleri (ikinci passkey, e-posta destekli destek süreci), denetim kayıtları ve ayrıntılı telemetriyi (başarı/başarısızlık oranları, tarayıcı/cihaz dağılımı) planlayın. Parolasız geleceğe adım atmak için bugün küçük bir pilotla başlayabilir, kullanıcılarınızdan gelen geri bildirimlere göre akışı iyileştirebilirsiniz.

Hiç yorum yok: