Module (NXM)
So ist das Kundenportal gebaut
Die Teile hinter einem Kundenportal, was jeder von ihnen weiß und was er nie sieht, und der Weg einer Anfrage vom Browser des Besuchers bis zum Moduldienst und zurück.
Eine Ferienhausagentur betreibt ihre Buchungsseite mit nexxus. Gäste suchen auf einer Karte, öffnen ein Haus, sehen die freien Tage und den Preis für ihren Aufenthalt und schicken eine Anfrage, die im Posteingang der Agentur landet. Weder nexxus noch die Portal-App enthalten dafür Code über Ferienhäuser. Was eine Unterkunft ist, welche ihrer Felder ein Gast sehen darf und wie ein Preis entsteht, gehört alles zum Paket der Agentur. Ein anderes Paket veröffentlicht seine Datensätze auf dieselbe Weise, ohne dass sich an nexxus etwas ändert.

Diese Seite erklärt die Teile und wie sie zusammenarbeiten. Wie Sie den Abschnitt portal eines Manifests schreiben, steht unter Kundenportal.
Vier Teile, jeder mit einer Aufgabe
Abschnitt betitelt „Vier Teile, jeder mit einer Aufgabe“| Teil | Was er tut | Was er nie tut |
|---|---|---|
| nexxus | Findet den Mandanten anhand der Webadresse, hält die Datensätze, entscheidet, was öffentlich ist, liefert Bilder und Karte aus und reicht Aufrufe von Endpunkten an den Dienst weiter | Code eines Pakets ausführen. Jemanden unter einer Portal-Adresse anmelden lassen |
| Das Paket | Erklärt in seinem Manifest die Entitäten, die öffentlichen Felder und Einstellungen, die Seiten und die Endpunkte | Einen Webserver mitbringen oder Code, der in nexxus läuft |
| Der Moduldienst | Rechnet aus, wofür es Logik braucht: freie Tage, einen Preis, eine Buchungsanfrage, eine Nachricht an den Gastgeber | Eigene Daten oder Zugangsdaten halten. Er liest und schreibt über die Datensatz-Schnittstelle von nexxus, mit einem Token, das nach Minuten abläuft |
| Die Portal-App | Zeichnet die Seiten, die das Paket erklärt, zuerst auf dem Server, dann im Browser | Etwas über eine Branche wissen. Etwas auf dem Gerät des Besuchers speichern |
Dieselben Datensätze bedienen zwei Gruppen. Die Mitarbeitenden der Agentur arbeiten in nexxus mit ihnen, in den Listen, Kalendern und Kartenansichten des Pakets, mit ihren Rechten und dem KI-Assistenten. Gäste sehen im Portal den öffentlichen Teil davon. Dazwischen gibt es keine Kopie und keinen Export: Ein Haus, das die Agentur auf inaktiv setzt, verschwindet innerhalb einer Minute von der Seite, weil Antworten der Portal-Schnittstelle 60 Sekunden lang gehalten werden dürfen.
Eine Anfrage von Anfang bis Ende
Abschnitt betitelt „Eine Anfrage von Anfang bis Ende“Ein Gast öffnet die Seite einer Unterkunft und wählt Reisedaten:
- 1GET /de/stays/villa-silvertreeBrowser → Portal-App
- 2Site, Seitendefinition und Unterkunft, mit dem Host des BesuchersPortal-App → nexxus
- 3Host zu Mandant, öffentlicher Datensatz, nur öffentliche Feldernexxus
- 4Die fertige SeitePortal-App → Browser
- 5GET /public/portal/<modul>/endpoints/quote?record=12&check_in=...Browser → nexxus
- 6Rate-Limit, erklärte Parameter, Datensatz ist öffentlichnexxus
- 7POST /portal/quote mit einem Aufruf-Token (60 s)nexxus → Moduldienst
- 8Token tauschen, die Datensätze lesen, die der Preis brauchtModuldienst → nexxus
- 9Das Angebot als JSONModuldienst → nexxus
- 10Das Angebot, Ablehnungen bereinigtnexxus → Browser
- Die erste Antwort ist eine fertige Seite. Die Portal-App fragt nexxus nach Site, Seitendefinition und Datensatz und schickt den Host des Besuchers mit (
X-Forwarded-Host), weil nexxus den Mandanten am Host erkennt. Suchmaschinen lesen die Seite so, wie sie ist. Im Browser übernimmt die App, ohne dieselben Daten noch einmal abzufragen. - Alles danach geht vom Browser an
/public/portal/...unter derselben Adresse: weitere Seiten, die nächste Seite der Treffer, der Kartenausschnitt, Preise und Formulare. - Endpunkte laufen über nexxus. nexxus prüft den Aufruf, bevor der Dienst ihn sieht, und die Antwort des Dienstes, bevor der Besucher sie sieht. Ein Dienst, der nicht erreichbar ist oder länger als 10 Sekunden braucht, wird für den Besucher zu
503, ohne einen Text des Dienstes darin.
Eine Adresse, ein Mandant
Abschnitt betitelt „Eine Adresse, ein Mandant“Die Domains eines Mandanten haben eine Rolle. Seine eigenen Domains tragen die App und die Anmeldung, seine Portal-Domains das Portal und sonst nichts. Beide setzt ein Superadmin unter AdministrationUnternehmenMandanten.
- Der Mandant kommt allein aus dem Host, nie aus einem Parameter, einem Cookie oder einem Header, den der Reverse Proxy nicht gesetzt hat.
X-Forwarded-Hostübernimmt nexxus nur von Proxys mit privaten Adressen. - Ein Portal-Host beantwortet zwei Pfade: die Portal-Schnittstelle unter
/public/portal/und die Karte unter/public/map/. Anmeldung, die Schnittstelle der App, der Live-Kanal und alles andere antworten dort mit404, als gäbe es sie nicht. Auf jedem anderen Host antwortet die Portal-Schnittstelle mit404. - Die Portal-App zeichnet Seiten nur für die Hosts, für die sie eingerichtet ist, damit ein gefälschter
Host-Header sie keine Daten von einer anderen Adresse holen lässt. - Seiten auf anderen Websites können die Portal-Schnittstelle im Browser nicht lesen: Sie erlaubt Aufrufe von fremden Ursprüngen nur von den Portal-Hosts des eigenen Mandanten, und nie mit Cookies.
Was nexxus verlässt, und wer es prüft
Abschnitt betitelt „Was nexxus verlässt, und wer es prüft“Das Portal bekommt immer nur, was das Paket als öffentlich erklärt hat, und nexxus prüft das an vier Stellen.
- Beim Hochladen. Die Paketprüfung lehnt ein Portal ab, das einen Kontakt, eine Person, ein JSON-Feld oder ein Feld veröffentlicht, das es nicht gibt, das auf einem nicht indexierten Feld filtert oder eine Seite, einen Endpunkt oder einen Dienst nennt, der fehlt. Siehe Was die Paketprüfung verlangt.
- Bei der Installation. Die Administration stimmt
portal:publiczu, angezeigt als ein Satz, den nexxus aus dem Manifest baut: welche Datensätze, welche Felder, dass Bilder und ein gerundeter Standort mitgehen, welchen Dienst Besucher aufrufen können. Ein Update, das mehr veröffentlicht, fragt erneut. - Bei jeder Antwort. nexxus gibt nur die Datensätze heraus, die der öffentliche Filter der Entität auswählt, und nur die Felder aus
public.<entität>.fields. Nicht veröffentlichbare Typen lässt es noch einmal weg, auch bei einem Manifest, das vor einer Regel gespeichert wurde. Einen Standort rundet es auf zwei Nachkommastellen (etwa 1 km), wenn das Manifest nichtexactsagt. Bilder bekommen eine Adresse, die für Mandant, Installation, Datensatz und Dokument signiert ist; jeder Abruf prüft erneut, ob der Datensatz öffentlich ist und das Bild noch nennt, und nur JPEG, PNG, WebP, GIF und AVIF gehen hinaus. - Bei jedem Aufruf eines Endpunkts. nexxus zählt den Aufruf zuerst gegen das Rate-Limit, reicht dann nur die erklärten Parameter weiter (je höchstens 200 Zeichen), prüft, ob
recordein öffentlicher Datensatz ist, lehnt einen Body über 32 KB ab und prüft das Formular Feld für Feld. Ein ausgefülltes Honeypot-Feld bekommt eine freundliche Antwort und geht nirgendwohin. Von der Antwort des Dienstes bekommt der Besucher höchstens 64 KB JSON oder eine Ablehnung, deren Texte auf schlichten Text gekürzt sind.
Der Moduldienst prüft alles noch einmal, denn der Aufruf kommt aus dem Internet.
Der Moduldienst hält nichts
Abschnitt betitelt „Der Moduldienst hält nichts“Der Dienst ist ein eigener Prozess. nexxus ruft ihn mit einem Aufruf-Token auf, dessen Auslöser portal:<endpunkt> ist; ein Token für den Preis kann deshalb keine Buchungsanfrage schicken. Hinter einem Portal-Aufruf steht keine Person: Ruft der Dienst zurück, handelt er als Dienstkonto der Installation, mit den Berechtigungen, denen die Administration zugestimmt hat. Wie die Tokens funktionieren, steht unter Moduldienste.
Was der Dienst schreibt, erscheint in nexxus wie jeder andere Datensatz. Im Ferienhaus-Paket wird aus einer Buchungsanfrage ein Gast (über die E-Mail-Adresse gefunden, sonst neu), eine Buchung mit dem Status Anfrage und die Nachricht des Gastes im Posteingang der Agentur. Standardmäßig entwirft der Dienst eine Antwort aus den Feldern der Unterkunft und hält WLAN und Anreisedetails zurück, bis der Aufenthalt gebucht ist. Mitarbeitende lesen den Entwurf, ändern ihn bei Bedarf und geben ihn frei.
Die Karte kommt von nexxus
Abschnitt betitelt „Die Karte kommt von nexxus“Die Karte im Portal und die Kartenansichten in nexxus nutzen dieselbe Komponente und dieselbe Quelle: ein PMTiles-Archiv mit OpenStreetMap-Daten, dazu seine Schriften und Symbole, ausgeliefert von nexxus unter /public/map/. Der Browser liest das Archiv in Byte-Bereichen, deshalb braucht nexxus keinen Kachelserver. Vom Browser des Besuchers geht keine Anfrage an einen Kartenanbieter.
Die Karte gehört der Installation, nicht einem Mandanten. Ein Archiv kann die Welt in niedrigen Zoomstufen und die Regionen, die eine Installation bedient, in voller Tiefe enthalten; außerhalb dieser Regionen hört die Karte auf zu zoomen, statt leere Kacheln zu zeigen.
Adresssuche und geocodeFrom von Paketfeldern laufen nur auf dem Server. Standardmäßig fragen sie den öffentlichen Nominatim-Server der OpenStreetMap Foundation, höchstens einmal pro Sekunde, wie dessen Nutzungsregeln es verlangen, und behalten jede Antwort 180 Tage (eine Adresse ohne Treffer 7 Tage).
Nichts auf dem Gerät des Besuchers
Abschnitt betitelt „Nichts auf dem Gerät des Besuchers“Die Portal-App setzt keine Cookies und nutzt weder Local Storage noch Session Storage oder IndexedDB. Seiten, Daten, Bilder, Kartenkacheln und Schriften kommen alle von der eigenen Adresse des Portals. Beim Verschieben der Karte suchen bleibt für den Besuch im Speicher. Deshalb braucht eine Seite auf dieser Grundlage keinen Cookie-Banner. Halten Sie das so, wenn Sie auf dem Portal aufbauen, und sagen Sie es in der Datenschutzerklärung der Seite, wie es das Ferienhaus-Paket tut.