Menu
CoddyTech

Sprawdzanie hasła

Część sekcji Uwierzytelnianie i bezpieczeństwo ścieżki Node.js w Coddy. Lekcja 2 z 17.

Haszowania nie można odwrócić, więc podczas logowania nigdy nie odczytuje się z powrotem zapisanego hasła. Haszujesz podane hasło w ten sam sposób i porównujesz oba klucze. Ten sam sposób oznacza tę samą sól: rozdziel zapisane salt:hash i ponownie użyj zawartej w nim soli.

Porównuj za pomocą timingSafeEqual, a nie ===. === kończy porównywanie na pierwszym różniącym się bajcie, więc napastnik, który mierzy czas wielu prób, może się dowiedzieć, jaka część odgadniętej wartości była poprawna. timingSafeEqual zawsze działa przez taki sam czas. Porównuje dwa bufory tej samej długości i zgłasza wyjątek, gdy ich długości się różnią.

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') zamienia tekst szesnastkowy z powrotem na bajty.

challenge icon

Wyzwanie

Łatwy
  • W pliku passwords.js dodaj i wyeksportuj verifyPassword(password, stored): zwraca wartość true, gdy hasło utworzyło tę zapisaną wartość.
  • W pliku server.js dodaj POST /login z { username, password }: 200 { username } albo 401 { "error": "Wrong username or password" } w przypadku błędnego hasła lub nieznanej nazwy.

Zarejestruj ada, zaloguj się, a następnie zaloguj się przy użyciu błędnego hasła.

Spróbuj swoich sił

import { randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';

const scryptAsync = promisify(scrypt);

// Przekształca hasło w tekst przechowywany przez signup.
export async function hashPassword(password) {
    const salt = randomBytes(16).toString('hex');
    const key = await scryptAsync(password, salt, 64);
    return `${salt}:${key.toString('hex')}`;
}

Wszystkie lekcje w sekcji Uwierzytelnianie i bezpieczeństwo