"""Passwort-Hashing (argon2id) und Token-Helfer für Sitzungen. argon2id ist der aktuelle Empfehlungsstandard und hat – anders als bcrypt – keine 72-Byte-Grenze. Die Sitzungs-Tokens selbst werden nur als SHA-256-Hash gespeichert, damit ein Blick in die Datenbank keine gültigen Cookies verrät. """ import hashlib import secrets from argon2 import PasswordHasher from argon2.exceptions import VerifyMismatchError, VerificationError, InvalidHashError _hasher = PasswordHasher() def hash_password(password: str) -> str: return _hasher.hash(password) def verify_password(password: str, password_hash: str) -> bool: try: return _hasher.verify(password_hash, password) except (VerifyMismatchError, VerificationError, InvalidHashError, TypeError): return False def needs_rehash(password_hash: str) -> bool: """True, wenn der Hash mit veralteten Parametern erzeugt wurde.""" try: return _hasher.check_needs_rehash(password_hash) except (InvalidHashError, TypeError): return False def generate_session_token() -> str: """Zufälliges, langlebiges Sitzungs-Token (Klartext, nur im Cookie).""" return secrets.token_urlsafe(32) def hash_session_token(token: str) -> str: """SHA-256 – schnell genug, um bei jeder Anfrage geprüft zu werden.""" return hashlib.sha256(token.encode("utf-8")).hexdigest()