4.0 KiB
Go HTMX Chat
Ein kleiner webbasierter Chat-Server mit Go, HTMX, Server-Sent Events, Datei-Persistenz und optionalem Pocket-ID/OIDC-Login.
Features
- mehrere Chaträume
- neue Räume über das UI erstellen
- Rollen:
user,moderator,admin - Raumrechte getrennt für Lesen und Schreiben
- private Räume über Mitgliederlisten
- Admin-Seite für Rollen, Raumrechte und Nachrichten-Aufräumen
- lokaler Entwicklungslogin oder echter Login via Pocket ID / OpenID Connect
- signierte HttpOnly-Session-Cookies
- Nachrichten senden per HTMX POST
- Live-Updates per Server-Sent Events
- persistente Speicherung in
data/chat.json - keine Node-/Frontend-Build-Toolchain
- responsives Dark-UI
Start im lokalen Entwicklungsmodus
go run ./cmd/server
Dann öffnen:
http://localhost:8080
Optional:
go run ./cmd/server -addr :3000 -db data/dev-chat.json
Pocket ID / OIDC Login aktivieren
Lege in Pocket ID einen OIDC Client an und trage als Callback URL ein:
http://localhost:8080/auth/callback
Für produktiven Betrieb mit Reverse Proxy entsprechend:
https://chat.example.com/auth/callback
Dann den Chat mit diesen Umgebungsvariablen starten:
export AUTH_MODE=oidc
export OIDC_ISSUER=https://id.example.com
export OIDC_CLIENT_ID=<client-id-aus-pocket-id>
export OIDC_CLIENT_SECRET=<client-secret-aus-pocket-id>
export OIDC_REDIRECT_URL=http://localhost:8080/auth/callback
export OIDC_SCOPES="openid profile email"
export SESSION_SECRET=$(openssl rand -base64 32)
export CHAT_ADMINS=j.bergner.hilden@gmail.com
export ROOM_CREATE_ROLES=admin,moderator
go run ./cmd/server
Hinweise:
OIDC_ISSUERist die Basis-URL deiner Pocket-ID-Instanz, zum Beispielhttps://id.example.com.- Die App liest automatisch
/.well-known/openid-configurationund verwendet daraus Authorization-, Token- und UserInfo-Endpunkte. - Als Anzeigename wird bevorzugt
preferred_usernamegenutzt, danachname,emailund zuletztsub. - Hinter einem HTTPS-Reverse-Proxy sollte
X-Forwarded-Proto: httpsgesetzt werden, damit Cookies alsSecuremarkiert werden.
Berechtigungssystem
Die App kennt drei globale Rollen:
user: normaler Nutzermoderator: kann standardmäßig Räume erstellen und darf member-Räume betretenadmin: darf alles verwalten
Der erste bekannte Benutzer wird automatisch Admin. Zusätzlich kannst du feste Admins über CHAT_ADMINS setzen. Der Wert ist eine kommaseparierte Liste aus Benutzernamen, E-Mail-Adressen oder OIDC-Subjects:
export CHAT_ADMINS="jan,j.bergner.hilden@gmail.com"
Wer Räume erstellen darf, steuerst du über:
export ROOM_CREATE_ROLES="admin,moderator"
Pro Raum gibt es getrennte Regeln für Lesen und Schreiben:
everyone: alle eingeloggten Benutzermembers: nur eingetragene Mitglieder, Moderatoren und Adminsmoderators: Moderatoren und Adminsadmins: nur Admins
Admins finden die Verwaltung unter /admin. Dort können sie Benutzerrollen ändern, Raumrechte setzen und alte Nachrichten löschen.
Alte Nachrichten aufräumen
Unter /admin gibt es eine Retention-Aktion. Beispiel: 90 löscht alle Nachrichten, die älter als 90 Tage sind. Die Löschung ist dauerhaft, weil die aktuelle Persistenz in data/chat.json direkt überschrieben wird.
Projektstruktur
cmd/server/main.go Einstiegspunkt
internal/chat/hub.go SSE-Broadcast pro Raum
internal/store/store.go einfache JSON-Persistenz
internal/web/auth.go lokaler Login + OIDC/OAuth2 Flow
templates/ HTML Templates
static/app.css Styling
Hinweise zur Sicherheit
Diese Version ist gut als Basis für einen privaten oder internen Chat geeignet. Für öffentlich produktiven Betrieb wären zusätzlich sinnvoll:
- CSRF-Schutz für schreibende POST-Routen
- Rate-Limits für Login, Raum-Erstellung und Nachrichten
- SQLite oder PostgreSQL als Store
- SQLite oder PostgreSQL als Store mit Migrationen
- vollständige ID-Token/JWKS-Prüfung mit einer OIDC-Library
- sichere Reverse-Proxy-Konfiguration mit HTTPS