myCRM/docs/LOGIN.md
2025-11-08 10:26:44 +01:00

302 lines
7.0 KiB
Markdown

# Login & Authentifizierung
## Übersicht
myCRM verwendet **Symfony Security** mit form-based Login und optionaler "Remember Me" Funktionalität.
## Features
**Email-basierter Login** - Benutzer melden sich mit ihrer Email-Adresse an
**Sicheres Password Hashing** - Automatisch mit Symfony Password Hasher
**Remember Me** - "Angemeldet bleiben" für 7 Tage
**CSRF Protection** - Schutz vor Cross-Site Request Forgery
**Automatische Weiterleitung** - Nach Login zum Dashboard
**Last Login Tracking** - Speichert Zeitpunkt des letzten Logins
**Inaktive User Blocking** - User mit `isActive = false` können sich nicht einloggen
**Vue.js Integration** - User-Daten werden an Frontend übergeben
## URLs
| Route | Zweck |
|-------|-------|
| `/login` | Login-Seite |
| `/logout` | Logout (POST) |
| `/` | Dashboard (nach Login) |
## Test-Benutzer
Nach `doctrine:fixtures:load` verfügbar:
```
Administrator:
Email: admin@mycrm.local
Passwort: admin123
Rechte: Vollzugriff auf alle Module
Vertriebsmitarbeiter:
Email: sales@mycrm.local
Passwort: sales123
Rechte: Kontakte, Deals, Aktivitäten (ohne Löschrechte)
```
⚠️ **Wichtig:** Diese Passwörter nur für Development verwenden!
## Security Configuration
```yaml
# config/packages/security.yaml
security:
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
main:
form_login:
login_path: app_login
check_path: app_login
default_target_path: /
logout:
path: app_logout
target: app_login
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week
access_control:
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/, roles: ROLE_USER }
```
## Backend Usage
### Controller: Aktuellen User abrufen
```php
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class MyController extends AbstractController
{
public function index(): Response
{
// Get current user
$user = $this->getUser();
if (!$user) {
throw $this->createAccessDeniedException();
}
// User properties
$email = $user->getEmail();
$fullName = $user->getFullName();
$isActive = $user->isActive();
$lastLogin = $user->getLastLoginAt();
// Check roles
if ($this->isGranted('ROLE_ADMIN')) {
// Admin stuff
}
return $this->render('template.html.twig', [
'user' => $user
]);
}
}
```
### Service: User von Security Token
```php
use Symfony\Bundle\SecurityBundle\Security;
class MyService
{
public function __construct(
private Security $security
) {}
public function doSomething(): void
{
$user = $this->security->getUser();
if ($user instanceof \App\Entity\User) {
// Work with user
}
}
}
```
### Twig: User-Informationen
```twig
{% if app.user %}
<p>Angemeldet als: {{ app.user.fullName }}</p>
<p>Email: {{ app.user.email }}</p>
{% if is_granted('ROLE_ADMIN') %}
<a href="/admin">Admin-Bereich</a>
{% endif %}
{% else %}
<a href="{{ path('app_login') }}">Login</a>
{% endif %}
```
## Frontend Usage (Vue.js)
### Auth Store (Pinia)
```javascript
import { useAuthStore } from '@/stores/auth';
// In Component
const authStore = useAuthStore();
// Check authentication
if (authStore.isAuthenticated) {
console.log('User:', authStore.user);
console.log('Full Name:', authStore.fullName);
}
// Check roles
if (authStore.hasRole('ROLE_ADMIN')) {
// Show admin features
}
if (authStore.isAdmin) {
// Shortcut for ROLE_ADMIN check
}
// Logout
authStore.logout();
```
### In Vue Components
```vue
<template>
<div>
<p v-if="authStore.isAuthenticated">
Willkommen, {{ authStore.fullName }}!
</p>
<button @click="authStore.logout()">
Abmelden
</button>
</div>
</template>
<script setup>
import { useAuthStore } from '@/stores/auth';
const authStore = useAuthStore();
</script>
```
## Event Listeners
### LoginSuccessListener
Wird automatisch nach erfolgreichem Login ausgeführt:
```php
// src/EventListener/LoginSuccessListener.php
#[AsEventListener(event: LoginSuccessEvent::class)]
class LoginSuccessListener
{
public function __invoke(LoginSuccessEvent $event): void
{
$user = $event->getUser();
// Update last login timestamp
$user->setLastLoginAt(new \DateTimeImmutable());
$this->entityManager->flush();
}
}
```
Du kannst weitere Listener hinzufügen für:
- Audit Logging
- Login-Benachrichtigungen
- Session-Tracking
- etc.
## Password Management
### Passwort ändern
```php
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
public function changePassword(
User $user,
string $newPassword,
UserPasswordHasherInterface $passwordHasher
): void {
$hashedPassword = $passwordHasher->hashPassword($user, $newPassword);
$user->setPassword($hashedPassword);
$this->entityManager->flush();
}
```
### Neuen User erstellen
```php
$user = new User();
$user->setEmail('neuer@user.de');
$user->setFirstName('Max');
$user->setLastName('Mustermann');
$user->setIsActive(true);
$user->setRoles(['ROLE_USER']);
$hashedPassword = $passwordHasher->hashPassword($user, 'passwort123');
$user->setPassword($hashedPassword);
$entityManager->persist($user);
$entityManager->flush();
```
## Security Best Practices
1.**Password Hashing** - Automatisch mit bcrypt/argon2
2.**CSRF Protection** - Aktiviert für Login-Form
3.**Remember Me Cookie** - Sicher mit Secret Key
4.**Inactive User Check** - User mit `isActive = false` blockiert
5.**Access Control** - Alle Routen außer `/login` erfordern Authentication
6.**HTTPS Recommended** - In Production immer HTTPS verwenden
7.**Session Security** - Symfony Session-Handling
## Troubleshooting
### "Access Denied" nach Login
- Prüfe `User::getRoles()` - muss mindestens `['ROLE_USER']` zurückgeben
- Prüfe `access_control` in `security.yaml`
### "Bad credentials"
- Passwort falsch eingegeben
- User existiert nicht
- User ist inaktiv (`isActive = false`)
### Remember Me funktioniert nicht
- Secret Key in `.env` gesetzt?
- Cookie wird vom Browser blockiert?
- Lifetime abgelaufen?
### Logout funktioniert nicht
- Sicherstellen dass `/logout` als POST Route konfiguriert ist
- CSRF-Token prüfen
## Next Steps
- [ ] Password Reset Funktionalität
- [ ] Two-Factor Authentication (2FA)
- [ ] OAuth Integration (Google, Microsoft)
- [ ] Rate Limiting für Login-Versuche
- [ ] Login History/Audit Log
- [ ] Email-Verifizierung bei Registrierung