Parolayı Doğrulama
Coddy'nin Node.js Journey'sinin Kimlik Doğrulama ve Güvenlik bölümünün bir parçası. Ders 6 / 24.
Giriş işlemi, kaydedilmiş tuzu ve özgün anahtar uzunluğunu kullanarak girilen paroladan bir anahtar türetir. Yeni bir tuz, doğru parola için bile farklı bir anahtar üretir. Özgün parola depolamadan hiçbir zaman çözülmez.
// Bir davet kodu salt.keyHex biçiminde saklandı
const [salt, keyHex] = savedInvite.split('.');
const expected = Buffer.from(keyHex, 'hex');
const attempted = await scryptAsync(inviteCode, salt, 32);Uzunluklarının eşleştiğini doğruladıktan sonra, elde edilen bayt dizilerini timingSafeEqual kullanarak karşılaştır. Bu, zamanlama yoluyla bilgi açığa çıkarabilecek, içeriğe bağlı erken çıkışı önler. Buffer için === kimliği denetler; normal bir dize karşılaştırması ise sabit zamanlı çalışma garantisi sağlamaz. Parola işlevin, parola kaydının iki nokta üst üste ayırıcısını ve 64 baytlık anahtarını kullanır. Eklediğin POST /login rotası, sonucu 200 veya 401 döndürmek için kullanır.
Görev
KolayBu adım, Never Store Passwords dersindeki proje dosyalarınız yerine, kurs için hazırlanmış özel notlar API projesini açar (passwords.js dahil). Önceki çalışmalarınız kendi dersinde kalır. passwords.js dosyasını düzenlemeden önce sağlanan dosyaları okuyun. Bu kopyada parola karma yardımcıları ve sağlanan hata ayıklama rotaları bulunur.
Kaydolma artık tuzlanmış özetleri kaydediyor. Kaydolma sırasında kaydedilen değerle parolayı denetleyen bir giriş işlevi ekleyin.
passwords.jsdosyasındaasyncbirverifyPassword(password, stored)işlevi ekleyip dışa aktarın.stored, kaydolma sırasında kaydedilen bir değerdir; örneğinf2bb...f065:c3f7...dbd2.passwordbu değeri oluşturan parolaysatrue, değilsefalsedöndürün:- İki noktadan önceki tuzu alın.
passworddeğerini bu tuzla,hashPasswordişlevindekiyle aynı şekilde 64 baytlık bir anahtara dönüştürün.- İki noktadan sonraki kaydedilmiş anahtarı onaltılık biçimden çözün. İki anahtarın bayt uzunlukları farklıysa, Comparing Key Bytes bölümündeki gibi
timingSafeEqualçağrısı yapmadanfalsedöndürün. Aksi takdirde karşılaştırma sonucunu döndürün.
server.jsdosyasında,verifyPasswordişlevinihashPasswordişlevinin yanına içe aktarın.POST /loginrotasını ekleyin. Bu rota, örneğin{"username": "ada", "password": "correct horse"}gibi kaydolma işlemiyle aynı gövdeyi alır.- Bu kullanıcı adına sahip kullanıcıyı bulun.
verifyPasswordyavaştır ve bir promise döndürür; bu nedenle tamamlanmasını bekleyin. - Kullanıcı varsa ve parola doğruysa 200 durum koduyla
{"username": "ada"}yanıtını verin. - Aksi takdirde 401 durum koduyla
{"error": "Wrong username or password"}yanıtını verin. 401 Unauthorized, isteğin kim olduğunu kanıtlayamadığı anlamına gelir. - Yanlış parola ve kimsenin kaydolmadığı bir kullanıcı adı için aynı 401 yanıtını gönderin. Böylece yanıt gövdesi, hangi kullanıcı adlarının mevcut olduğunu kimseye asla bildirmez.
- Bu kullanıcı adına sahip kullanıcıyı bulun.
Deneyin: Run düğmesine basın. POST /signup isteğini {"username": "ada", "password": "correct horse"} ile gönderin: durum kodu 201. Aynı gövdeyle POST /login isteğini gönderin: durum kodu 200 ve {"username": "ada"}. POST /login isteğini {"username": "ada", "password": "wrong horse"} ile gönderin: durum kodu 401 ve {"error": "Wrong username or password"}. POST /login isteğini {"username": "nobody", "password": "correct horse"} ile gönderin: aynı 401 yanıtı.
Kendin dene
import { randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';
const scryptAsync = promisify(scrypt);
// Bir parolayı signup'ın sakladığı metne dönüştürür.
export async function hashPassword(password) {
const salt = randomBytes(16).toString('hex');
const key = await scryptAsync(password, salt, 64);
return `${salt}:${key.toString('hex')}`;
}
Kimlik Doğrulama ve Güvenlik bölümündeki tüm dersler
Kendi başına pratik yap: Express playground