75 lines
5.7 KiB
Markdown
75 lines
5.7 KiB
Markdown
# Optimierung des Domain-Routings und Session-Handlings
|
|
|
|
Dieses Dokument beschreibt eine vorgeschlagene Optimierung für die bestehende Domain-Routing- und Session-Verwaltungslogik.
|
|
|
|
## 1. Analyse der aktuellen Architektur
|
|
|
|
Die Anwendung nutzt eine komplexe, aber leistungsstarke Multi-Domain-Architektur, um verschiedene Anwendungsbereiche (Hauptseite, CRM, Partner-Portal, Checkout, User-Shops) voneinander zu trennen.
|
|
|
|
- **Konfiguration**: Die Domain-Struktur wird zentral in `config/domains.php` definiert.
|
|
- **Service Provider (`DomainServiceProvider`)**:
|
|
- Registriert den `DomainService` (zuständig für Domain-Analyse und UserShop-Logik).
|
|
- Registriert den `DomainContext` als Singleton, der pro Request Informationen über die aktuelle Domain enthält (Typ, Host, Subdomain, UserShop-Objekt).
|
|
- **Wichtig**: Er registriert die `DomainResolver`-Middleware und fügt sie an den _Anfang_ der `web`-Middleware-Gruppe hinzu.
|
|
- **Middleware (`DomainResolver`)**:
|
|
- Nutzt den `DomainContext`, um die Anfrage zu validieren.
|
|
- Leitet ungültige Domains auf die Hauptdomain um.
|
|
- Prüft den Status von User-Shops (aktiv, Zahlung etc.).
|
|
- **Problembereich**: Schreibt `UserShop`-Daten aktiv in die Session (`Session::put`, `Session::save`).
|
|
- **Routing (`RouteServiceProvider`)**: Lädt die passenden Routen-Dateien basierend auf dem `type` im `DomainContext`.
|
|
|
|
## 2. Identifiziertes Problem: Konflikte bei der Session-Erstellung
|
|
|
|
Das Kernproblem liegt in der Reihenfolge, in der die Middleware ausgeführt wird.
|
|
|
|
1. Der `DomainServiceProvider` registriert die `DomainResolver`-Middleware mit `prependMiddlewareToGroup('web', ...)`.
|
|
2. Dadurch wird `DomainResolver` **vor** der Standard-Laravel-Middleware `StartSession` ausgeführt, die ebenfalls Teil der `web`-Gruppe ist.
|
|
3. Die `DomainResolver`-Middleware versucht, auf die Session zuzugreifen und sie zu modifizieren (`Session::put`, `Session::save`). Da die `StartSession`-Middleware noch nicht gelaufen ist, wird hier möglicherweise eine "provisorische" Session gestartet.
|
|
4. Anschließend läuft die `StartSession`-Middleware, die die "offizielle" Session aus dem Cookie lädt.
|
|
5. Dies kann zu einem Konflikt führen, bei dem zwei verschiedene Session-Instanzen pro Anfrage existieren oder die in `DomainResolver` gespeicherten Daten nicht in der finalen Session-Response an den Client gesendet werden. Das Resultat ist, dass der `UserShop`-Kontext beim Wechsel zwischen Domains (z.B. vom Shop zum `in.`-Portal) verloren geht.
|
|
|
|
## 3. Vorgeschlagene Lösung: Saubere Trennung und korrekte Reihenfolge
|
|
|
|
Die vorgeschlagene Lösung zielt darauf ab, die Logik zu entzerren und die Middleware in der korrekten, von Laravel vorgesehenen Reihenfolge auszuführen.
|
|
|
|
### Schritt 1: Korrektur der Middleware-Reihenfolge
|
|
|
|
Die `DomainResolver`-Middleware darf nicht mehr per `prependMiddlewareToGroup` im Service Provider registriert werden. Stattdessen sollte sie im `app/Http/Kernel.php` innerhalb der `web`-Gruppe **nach** der `\Illuminate\Session\Middleware\StartSession`-Middleware platziert werden.
|
|
|
|
Dadurch wird sichergestellt, dass die Session immer korrekt initialisiert ist, bevor unsere anwendungsspezifische Logik darauf zugreift.
|
|
|
|
### Schritt 2: Aufteilung der Middleware-Verantwortlichkeiten
|
|
|
|
Die `DomainResolver`-Middleware hat aktuell zu viele Aufgaben. Eine Aufteilung verbessert die Lesbarkeit, Wartbarkeit und Einhaltung des Single-Responsibility-Prinzips.
|
|
|
|
**Vorschlag für neue Middleware-Struktur:**
|
|
|
|
1. **`InitializeDomainContext` (Neue Middleware)**:
|
|
|
|
- Diese Middleware läuft sehr früh (kann global oder am Anfang der `web`-Gruppe stehen).
|
|
- Ihre **einzige** Aufgabe ist es, den `DomainContext` zu initialisieren, indem sie `app(DomainContext::class)` aufruft. Sie führt **keine** Session-Operationen oder Umleitungen durch. Dies stellt sicher, dass der Kontext für alle nachfolgenden Teile der Anwendung (auch andere Middleware) verfügbar ist.
|
|
|
|
2. **`HandleDomainLogic` (Umbenannter `DomainResolver`)**:
|
|
- Diese Middleware läuft **nach** `StartSession`.
|
|
- Sie nutzt den bereits initialisierten `DomainContext`.
|
|
- **Aufgaben**:
|
|
- Umleitung bei `isUnknown()`.
|
|
- Validierung des `UserShop` (aktiv, bezahlt etc.).
|
|
- Persistierung des `UserShop`-Kontexts in der Session. Die Logik hierfür wird verfeinert, um den Shop-Kontext über Domain-Grenzen hinweg intelligent zu erhalten. Zum Beispiel wird der `user_shop` nicht mehr gelöscht, nur weil man die `main`-Domain besucht. Er wird nur überschrieben, wenn ein neuer Shop-Kontext explizit gesetzt wird.
|
|
|
|
### Schritt 3: Vereinfachung des Session-Handlings
|
|
|
|
Die `setupLegacyContext`-Methode wird überarbeitet. Das Ziel ist ein klares und vorhersehbares Verhalten:
|
|
|
|
- **Auf einer User-Shop-Domain**: Der `UserShop` wird in die Session geschrieben.
|
|
- **Auf einer Nicht-Shop-Domain (`crm`, `portal`, `checkout`, `main`)**: Die Session wird **nicht angerührt**. Der bestehende `UserShop` aus der Session bleibt erhalten, sodass eine Rückkehr zum Shop jederzeit möglich ist.
|
|
- **Wechsel zu einem anderen User-Shop**: Der neue `UserShop` überschreibt den alten Wert in der Session.
|
|
|
|
## 4. Vorteile der neuen Architektur
|
|
|
|
- **Stabilität**: Das Session-Problem wird an der Wurzel behoben, indem die Middleware-Reihenfolge korrigiert wird.
|
|
- **Klarheit**: Die Verantwortlichkeiten sind sauber getrennt. Eine Middleware für die Kontext-Initialisierung, eine für die Domain-Logik.
|
|
- **Wartbarkeit**: Einfacher zu verstehen und zu erweitern. Das `TECH-DEBT` in `setupLegacyContext` wird reduziert.
|
|
- **Performance**: Die Logik zur Domain-Analyse im `DomainServiceProvider` wird nur einmal ausgeführt, wenn der Kontext das erste Mal benötigt wird (lazy-loading), was beibehalten wird.
|
|
|
|
Die folgenden Dateien in diesem Ordner enthalten eine beispielhafte Implementierung dieses Vorschlags.
|