Authentifizierung mit serverseitigen Sitzungen, CSRF und Rollen

Passwoerter mit Argon2id, im Cookie steht nur ein Token und in der Datenbank
dessen Hash. Das CSRF-Token wird per HMAC aus dem Sitzungstoken abgeleitet
statt separat gespeichert - ohne das httpOnly-Cookie ist es nicht herstellbar.

TOTP ist optional und wird erst nach einem bestaetigten Code scharf geschaltet,
damit sich niemand bei der Einrichtung aussperrt.
This commit is contained in:
2026-09-18 11:33:25 +02:00
parent a1b764155a
commit 3d2b87297e
7 changed files with 336 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
import { hash, verify } from '@node-rs/argon2';
// OWASP-Empfehlung fuer Argon2id: 19 MiB, 2 Durchlaeufe, Parallelitaet 1.
const options = {
memoryCost: 19456,
timeCost: 2,
parallelism: 1,
} as const;
export function hashPassword(plain: string): Promise<string> {
return hash(plain, options);
}
export async function verifyPassword(digest: string, plain: string): Promise<boolean> {
try {
return await verify(digest, plain, options);
} catch {
// Kaputter oder fremdformatiger Hash gilt als nicht passend.
return false;
}
}
const MIN_LENGTH = 12;
export function validatePasswordStrength(plain: string): string | null {
if (plain.length < MIN_LENGTH) {
return `Passwort muss mindestens ${MIN_LENGTH} Zeichen lang sein`;
}
if (!/[a-z]/.test(plain) || !/[A-Z]/.test(plain)) {
return 'Passwort muss Gross- und Kleinbuchstaben enthalten';
}
if (!/[0-9]/.test(plain)) {
return 'Passwort muss mindestens eine Ziffer enthalten';
}
return null;
}