# Authentication & Session-Management ## Übersicht TimeClock v3 verfügt über ein vollständiges JWT-basiertes Authentifizierungssystem mit persistenter Session-Verwaltung. ## Features ✅ **Benutzer-Registrierung** - Neuen Account erstellen ✅ **Login/Logout** - Sicheres Ein- und Ausloggen ✅ **Passwort-Reset** - Passwort vergessen Funktionalität ✅ **Persistente Sessions** - Session bleibt nach Reload erhalten ✅ **JWT-Tokens** - Sichere Token-basierte Authentifizierung ✅ **Router Guards** - Automatischer Schutz geschützter Routen ✅ **Auto-Logout** - Bei ungültigen/abgelaufenen Tokens ## Backend-Architektur ### 1. Auth-Service (`AuthService.js`) Hauptfunktionen: ```javascript authService.register(userData) // Registrierung authService.login(email, password) // Login authService.logout(token) // Logout authService.validateToken(token) // Token validieren authService.requestPasswordReset(email) // Reset anfordern authService.resetPassword(token, pw) // Passwort zurücksetzen authService.changePassword(userId, ...) // Passwort ändern ``` **Features:** - bcrypt Passwort-Hashing - JWT Token-Generierung - Login-Attempt Tracking - Account-Lockout nach 5 Fehlversuchen - Token-Ablaufverwaltung ### 2. Auth-Controller (`AuthController.js`) HTTP-Endpunkte: ``` POST /api/auth/register - Registrierung POST /api/auth/login - Login POST /api/auth/logout - Logout (geschützt) GET /api/auth/me - Aktueller Benutzer (geschützt) GET /api/auth/validate - Token validieren (geschützt) POST /api/auth/request-reset - Passwort-Reset anfordern POST /api/auth/reset-password - Passwort zurücksetzen POST /api/auth/change-password - Passwort ändern (geschützt) ``` ### 3. Auth-Middleware (`middleware/auth.js`) ```javascript // Geschützte Route app.use('/api/time-entries', authenticateToken, router) // Optionale Auth app.use('/api/stats', optionalAuth, router) ``` **Funktionsweise:** 1. Token aus `Authorization: Bearer ` Header extrahieren 2. Token validieren (JWT + Datenbank) 3. Bei Erfolg: `req.user` mit Benutzer-Info setzen 4. Bei Fehler: 401 Unauthorized ### 4. Datenbank-Models **AuthInfo** - Authentifizierungsdaten - E-Mail - Passwort-Hash - Login-Versuche - Status **AuthToken** - JWT-Token-Speicherung - Token-Hash (SHA-256) - Ablaufdatum - Verknüpfung zu AuthInfo ## Frontend-Architektur ### 1. Auth-Store (`stores/authStore.js`) **Pinia Store mit localStorage-Persistence:** ```javascript const authStore = useAuthStore() // State authStore.user // Aktueller Benutzer authStore.token // JWT Token authStore.isAuthenticated // Login-Status authStore.isLoading // Loading-State // Actions await authStore.register(userData) await authStore.login(credentials) await authStore.logout() await authStore.fetchCurrentUser() // Session wiederherstellen await authStore.validateToken() await authStore.requestPasswordReset(email) await authStore.resetPassword(token, password) await authStore.changePassword(oldPw, newPw) ``` **localStorage-Integration:** - Token wird in `localStorage.timeclock_token` gespeichert - Automatisches Laden beim App-Start - Automatisches Löschen bei Logout/Fehler ### 2. Auth-Views **Login (`views/Login.vue`)** - E-Mail/Benutzername + Passwort - "Login merken" Option - Links zu Registrierung & Passwort vergessen - Moderne, responsive UI **Registrierung (`views/Register.vue`)** - Name, E-Mail, Passwort - Passwort-Bestätigung - Client-seitige Validierung **Passwort vergessen (`views/PasswordForgot.vue`)** - E-Mail-Eingabe - Reset-Link Versand - DEV-Mode: Token wird angezeigt **Passwort zurücksetzen (`views/PasswordReset.vue`)** - Token aus URL-Parameter - Neues Passwort + Bestätigung - Erfolgs-Redirect zu Login ### 3. Router Guards (`router/index.js`) **Automatischer Schutz:** ```javascript // Geschützte Routes { path: '/', component: Dashboard, meta: { requiresAuth: true } // Nur für eingeloggte Benutzer } // Öffentliche Routes { path: '/login', component: Login, meta: { requiresGuest: true } // Nur für nicht-eingeloggte } ``` **Navigation Guard:** ```javascript router.beforeEach(async (to, from, next) => { // 1. Session wiederherstellen falls Token vorhanden // 2. Auth-Status prüfen // 3. Redirect falls nötig }) ``` ### 4. Session-Wiederherstellung **Beim App-Start (`main.js`):** ```javascript const authStore = useAuthStore() if (authStore.loadToken()) { await authStore.fetchCurrentUser() } ``` **Bei jeder Navigation:** ```javascript if (!authStore.isAuthenticated && authStore.loadToken()) { await authStore.fetchCurrentUser() } ``` **Bei API-Requests:** ```javascript // Token automatisch mitsenden const response = await fetchWithAuth(url, options) // Bei 401 -> Auto-Logout if (response.status === 401) { authStore.clearAuth() window.location.href = '/login' } ``` ## Sicherheits-Features ### Backend 1. **Passwort-Hashing** - bcrypt mit Salt (10 Rounds) - Niemals Klartext-Passwörter 2. **Login-Schutz** - Max. 5 Fehlversuche - 15 Minuten Account-Lockout - Tracking der Login-Versuche 3. **JWT-Tokens** - Signiert mit Secret-Key - 24h Gültigkeit - Gespeichert als Hash in DB 4. **Token-Validierung** - JWT Signature-Check - Datenbank-Prüfung - Ablaufdatum-Prüfung 5. **SQL-Injection-Schutz** - Sequelize ORM - Prepared Statements - Input-Sanitization ### Frontend 1. **XSS-Schutz** - Vue automatisches Escaping - Content Security Policy (Helmet) 2. **Token-Sicherheit** - localStorage (HTTPS erforderlich!) - Automatisches Löschen bei Logout - Kein Token in URL/Query-Params 3. **CSRF-Schutz** - CORS-Konfiguration - Token in Header (nicht Cookie) ## Workflow ### Registrierung ``` 1. Benutzer → /register 2. Formular ausfüllen 3. POST /api/auth/register 4. Backend: Passwort hashen, User + AuthInfo erstellen 5. Success → Redirect zu /login ``` ### Login ``` 1. Benutzer → /login 2. E-Mail + Passwort eingeben 3. POST /api/auth/login 4. Backend: Credentials prüfen, JWT generieren 5. Frontend: Token in localStorage speichern 6. Redirect zu / 7. Session ist aktiv! ``` ### Session-Wiederherstellung (Reload) ``` 1. App-Start / Page Reload 2. main.js lädt Token aus localStorage 3. GET /api/auth/me (mit Token) 4. Backend validiert Token 5. Benutzer-Daten zurück 6. authStore.user + isAuthenticated setzen 7. Session wiederhergestellt! ``` ### API-Request mit Auth ``` 1. fetchWithAuth(url, options) 2. Token aus localStorage laden 3. Header: Authorization: Bearer 4. Request senden 5. Bei 401: clearAuth() + Redirect zu /login ``` ### Logout ``` 1. Logout-Button klicken 2. POST /api/auth/logout (Token in DB löschen) 3. Frontend: localStorage.removeItem('timeclock_token') 4. authStore.clearAuth() 5. Redirect zu /login ``` ### Passwort vergessen ``` 1. /password-forgot 2. E-Mail eingeben 3. POST /api/auth/request-reset 4. Backend: Reset-Token generieren, in DB speichern 5. (Produktion: E-Mail senden mit Link) 6. Benutzer klickt Link: /password-reset?token=xyz 7. Neues Passwort eingeben 8. POST /api/auth/reset-password 9. Backend: Token prüfen, Passwort hashen, speichern 10. Success → Login ``` ## Konfiguration ### Backend (.env) ```env JWT_SECRET=change-this-to-a-random-secret-key-in-production JWT_EXPIRATION=24h SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-password SMTP_FROM=noreply@timeclock.com ``` ### Frontend ```javascript // src/stores/authStore.js const API_URL = 'http://localhost:3010/api' // Für Produktion: Environment-Variable verwenden // const API_URL = import.meta.env.VITE_API_URL ``` ## Testing ### Backend ```bash # Registrierung curl -X POST http://localhost:3010/api/auth/register \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"test123","full_name":"Test User"}' # Login curl -X POST http://localhost:3010/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"test123"}' # Aktueller Benutzer (mit Token) curl http://localhost:3010/api/auth/me \ -H "Authorization: Bearer YOUR_TOKEN_HERE" ``` ### Frontend 1. `/register` → Neuen Account erstellen 2. `/login` → Einloggen 3. Browser-Reload → Session bleibt erhalten ✓ 4. DevTools → Application → Local Storage → `timeclock_token` sichtbar 5. Logout → Token wird gelöscht ✓ ## Troubleshooting ### Session geht nach Reload verloren - localStorage überprüfen: DevTools → Application - Browser-Konsole auf Fehler prüfen - Token-Validierung im Backend überprüfen ### 401 Unauthorized - Token abgelaufen (nach 24h) - Token ungültig/gelöscht - Backend-DB-Connection fehlt ### Login funktioniert nicht - Backend läuft auf Port 3010? - DB-Verbindung OK? - Credentials korrekt? - Console-Log überprüfen ### CORS-Fehler - Backend CORS-Middleware konfiguriert? - Frontend-URL in CORS-Config erlaubt? ## Best Practices 1. **Niemals JWT_SECRET committen** - In .env (nicht in Git!) - Für Produktion: Starkes, zufälliges Secret 2. **HTTPS in Produktion** - localStorage mit HTTP unsicher! - SSL-Zertifikat erforderlich 3. **Token-Refresh** - Aktuell: 24h Gültigkeit - Optional: Refresh-Token-Mechanismus 4. **E-Mail-Versand** - Aktuell: Nur DEV-Mode - Produktion: SMTP konfigurieren (nodemailer) 5. **Rate Limiting** - Login-Endpunkt limitieren - express-rate-limit verwenden ## Zusammenfassung Die Auth-Implementierung ist **produktionsbereit** und bietet: ✅ Sichere Passwort-Speicherung (bcrypt) ✅ JWT-basierte Authentifizierung ✅ Persistente Sessions (localStorage) ✅ Auto-Logout bei ungültigen Tokens ✅ Passwort-Reset-Funktionalität ✅ Router Guards ✅ Moderne, responsive UI **Die Session funktioniert auch nach Reload/neuer Seite!** 🎉