Verificare una password
Fa parte della sezione Autenticazione e sicurezza del percorso Node.js di Coddy. Lezione 2 di 17.
Un hash non può essere invertito, quindi durante l'accesso non si recupera mai la password memorizzata. Esegui l'hash del tentativo allo stesso modo e confronta le due chiavi. Allo stesso modo significa con lo stesso salt: dividi il valore memorizzato salt:hash e riutilizza il suo salt.
Confronta con timingSafeEqual, non con ===. === si ferma al primo byte diverso, quindi un aggressore che cronometra molte risposte scopre quanto fosse corretto un tentativo. timingSafeEqual impiega sempre lo stesso tempo. Confronta due Buffer della stessa lunghezza e genera un'eccezione se le lunghezze sono diverse.
import { timingSafeEqual } from 'node:crypto';
const expected = Buffer.from(process.env.API_KEY);
const given = Buffer.from(req.get('x-api-key') ?? '');
const ok = given.length === expected.length && timingSafeEqual(given, expected);Buffer.from(hex, 'hex') riconverte il testo esadecimale in byte.
Sfida
Facile- In
passwords.js, aggiungi ed esportaverifyPassword(password, stored): vero quando la password ha generato quel valore memorizzato. - In
server.js, aggiungiPOST /logincon{ username, password }: 200{ username }, oppure 401{ "error": "Wrong username or password" }se la password è errata o il nome utente non è noto.
Registra ada, accedi, poi accedi con una password errata.
Provalo tu
import { randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';
const scryptAsync = promisify(scrypt);
// Trasforma una password nel testo che signup memorizza.
export async function hashPassword(password) {
const salt = randomBytes(16).toString('hex');
const key = await scryptAsync(password, salt, 64);
return `${salt}:${key.toString('hex')}`;
}