Features: - Backend: Node.js/Express mit MySQL/MariaDB - Frontend: Vue.js 3 mit Composition API - UTC-Zeithandling für korrekte Zeiterfassung - Timewish-basierte Überstundenberechnung - Wochenübersicht mit Urlaubs-/Krankheits-/Feiertagshandling - Bereinigtes Arbeitsende (Generell/Woche) - Überstunden-Offset für historische Daten - Fixed Layout mit scrollbarem Content - Kompakte UI mit grünem Theme
3.9 KiB
ID-Hashing System
Übersicht
Das TimeClock Backend verwendet ein automatisches ID-Hashing-System, das alle numerischen IDs in API-Responses verschlüsselt und eingehende Hash-IDs automatisch entschlüsselt.
Warum ID-Hashing?
- Sicherheit: Verhindert, dass Angreifer die Anzahl der Datensätze erraten können
- Obfuscation: Versteckt die interne Datenbankstruktur
- Schutz vor ID-Enumeration: Verhindert systematisches Durchlaufen von Ressourcen
Funktionsweise
Automatisches Hashing (Backend → Frontend)
Alle numerischen ID-Felder in API-Responses werden automatisch in Hashes konvertiert:
// Datenbank-Daten:
{
id: 123,
user_id: 456,
full_name: "Max Mustermann"
}
// API-Response:
{
id: "xY9kL2mP3qR5.aB7cD8eF9gH0",
user_id: "tU6vW7xY8zZ9.iJ1kL2mN3oP4",
full_name: "Max Mustermann"
}
Automatisches Enthashen (Frontend → Backend)
Alle Hash-IDs in eingehenden Requests werden automatisch zurück in numerische IDs konvertiert:
// Frontend sendet:
{
user_id: "xY9kL2mP3qR5.aB7cD8eF9gH0"
}
// Backend erhält:
{
user_id: 123
}
Implementierung
Backend
Das System besteht aus drei Komponenten:
utils/hashId.js: Utility-Klasse für Encoding/Decodingmiddleware/hashResponse.js: Middleware für ausgehende Responsesmiddleware/unhashRequest.js: Middleware für eingehende Requests
Konfiguration
In der .env-Datei:
HASH_ID_SECRET=your-hash-id-secret-change-in-production
⚠️ Wichtig: Das Secret sollte in Produktion geändert werden und geheim bleiben!
Erkannte ID-Felder
Folgende Feldnamen werden automatisch als IDs erkannt und gehashed:
id,_iduser_id,userIdauth_info_id,authInfoIdauth_token_id,authTokenIdworklog_id,worklogIdvacation_id,vacationIdsick_id,sickIdholiday_id,holidayIdstate_id,stateIdsick_type_id,sickTypeIdweekly_worktime_id,weeklyWorktimeId
Frontend-Integration
Das Frontend muss keine Änderungen vornehmen - es arbeitet einfach mit den empfangenen Hash-IDs:
// GET /api/auth/me
const response = await fetch('/api/auth/me')
const data = await response.json()
console.log(data.user.id) // "xY9kL2mP3qR5.aB7cD8eF9gH0"
// POST /api/some-endpoint
await fetch('/api/some-endpoint', {
method: 'POST',
body: JSON.stringify({
user_id: data.user.id // Hash wird automatisch entschlüsselt
})
})
Manuelle Verwendung
Falls manuelles Encoding/Decoding nötig ist:
const hashId = require('./utils/hashId');
// Einzelne ID hashen
const hash = hashId.encode(123); // "xY9kL2mP3qR5.aB7cD8eF9gH0"
// Hash dekodieren
const id = hashId.decode(hash); // 123
// Objekt hashen
const obj = { id: 123, name: "Test" };
const hashed = hashId.encodeObject(obj); // { id: "xY9...", name: "Test" }
// Array hashen
const array = [{ id: 1 }, { id: 2 }];
const hashedArray = hashId.encodeArray(array);
Sicherheitshinweise
- Secret ändern: Ändern Sie
HASH_ID_SECRETin der Produktion - Secret sicher aufbewahren: Das Secret sollte niemals im Code oder in der Versionskontrolle erscheinen
- Keine zusätzliche Sicherheit: ID-Hashing ersetzt keine echte Autorisierung - prüfen Sie immer die Zugriffsrechte!
Hash-Format
Das Hash-Format: {encrypted_id}.{hash_prefix}
- encrypted_id: AES-256-CBC verschlüsselte ID
- hash_prefix: HMAC-SHA256 Hash (erste 12 Zeichen) zur Verifizierung
- Encoding: base64url (URL-sicher)
Beispiel: xY9kL2mP3qR5.aB7cD8eF9gH0
Fehlerbehandlung
Ungültige Hash-IDs werden zu null dekodiert. Services/Controller sollten dies behandeln:
const userId = req.params.id; // Könnte null sein wenn Hash ungültig
if (!userId) {
return res.status(400).json({ error: 'Ungültige ID' });
}
Performance
- Encoding: ~0.1ms pro ID
- Decoding: ~0.2ms pro ID
- Overhead: Minimal, da deterministisch und ohne Datenbank-Zugriff