-
Notifications
You must be signed in to change notification settings - Fork 0
Authentication DE
🌐 English · Deutsch
Das Dashboard authentifiziert Nutzer per Discord OAuth2 und hält die Session in einem signierten, serverseitig verwalteten Cookie. Das Sicherheitsmodell folgt einem Leitsatz: Geheimnisse erreichen nie den Browser. Das Discord-Client-Secret und das Gateway-Token liegen nur im SvelteKit-Server (dem BFF), das Gateway akzeptiert nur localhost plus Token, und jede privilegierte Aktion wird botseitig erneut gegen Reds Berechtigungssystem geprüft. Diese Seite erklärt den Login-Flow, das Session-Modell und die Berechtigungsstufen.

- Der Nutzer klickt Mit Discord anmelden. Der BFF (
GET /auth/login) erzeugt einen zufälligenstate-Wert, legt ihn in einem kurzlebigen httpOnly-Cookie ab und leitet den Browser zur Discord-Authorize-URL mit den Scopesidentifyundguildsweiter. - Der Nutzer bestätigt bei Discord und wird zurück an
DISCORD_REDIRECT_URI(/auth/callback) geschickt. - Der BFF (
GET /auth/callback) prüft den zurückgegebenenstategegen das Cookie und tauscht dann den Authorization-codeserverseitig perDISCORD_CLIENT_SECRETgegen ein Access-Token. - Mit diesem Token holt der BFF den Discord-Nutzer (
identify) und leitet die UI-Locale ab (de-DEfür deutsche Nutzer, sonsten-US). - Der BFF erzeugt eine Session und setzt das signierte Session-Cookie. Der Browser sieht weder das Client-Secret noch die rohe Token-Verarbeitung.
Browser ──/auth/login──▶ BFF ──Redirect──▶ Discord
Browser ◀──Consent────── Discord
Browser ──/auth/callback (code,state)──▶ BFF ──code→Token (Secret)──▶ Discord
BFF ◀──User──────────────── Discord
Browser ◀──Set-Cookie: dks_session────── BFF
Die Session steckt in einem Cookie namens dks_session. Es ist kein opaker Datenbank-Key, sondern die Nutzer-Payload plus eine HMAC-SHA256-Signatur mit SESSION_SECRET:
dks_session = base64url(payload) . base64url(HMAC-SHA256(payload, SESSION_SECRET))
| Eigenschaft | Wert |
|---|---|
| Cookie-Name | dks_session |
| Signatur | HMAC-SHA256, mit konstanter Zeit verglichen |
| Flags |
httpOnly, sameSite=lax, in Produktion secure
|
| Lebensdauer | 7 Tage |
| Payload | User-ID, Username, Avatar, Locale, Issued-at (iat), Token-Daten |
Da das Cookie signiert (nicht verschlüsselt) ist, kann es nicht manipuliert werden: Jede Änderung der Payload bricht den HMAC. Signieren und Prüfen passieren ausschließlich im BFF (lib/server/session.ts), das SESSION_SECRET verlässt den Server also nie.
Der Bot-Owner kann alle Sessions auf einmal invalidieren („Sessions zurücksetzen" in Einstellungen). Das setzt einen session_epoch-Zeitstempel im Cog. Bei jeder Anfrage vergleicht der BFF die iat der Session mit der aktuellen Epoch (für ~60 s gecacht, um einen Round-Trip pro Anfrage zu sparen) und verwirft Sessions, die älter als die Epoch sind.
Der BFF spricht über das JSON-RPC-Gateway des Cogs mit dem Bot. Zwei Dinge schützen es:
-
Localhost-Bindung. Das Gateway lauscht standardmäßig auf
127.0.0.1– aus dem Netzwerk nicht erreichbar. -
Geteiltes Token. Jede BFF-Anfrage trägt den Header
X-Dashboard-Token. Der Cog vergleicht ihn in konstanter Zeit (compare_digest). Nur der BFF kennt das Token.
Der Browser spricht nie direkt mit dem Gateway. Er ruft immer nur die eigenen /api/*-Endpunkte des BFF auf, die dann serverseitig das Gateway ansprechen. Siehe API & Gateway zum Protokoll.
Beim Auflisten der Server liefert das Gateway nur Gilden zurück, in denen der Nutzer tatsächlich Mitglied ist (oder in denen er Bot-Owner ist). Selbst innerhalb eines Gilden-Kontexts kann ein eingeloggter Nicht-Mitglied die Daten dieser Gilde nicht lesen: Der Server erzwingt für jeden gildenbezogenen Call mindestens guild_member, sodass ein manipuliertes guild_id keinen fremden Server-Inhalt leaken kann.
Jeder Beitrag (Widget, Panel, Liste, Seite) und jede privilegierte RPC-Methode deklariert eine Mindeststufe. Das Gateway leitet die effektive Stufe des Nutzers aus Reds eigenem Berechtigungssystem ab und erzwingt sie serverseitig bei jedem Call – das Frontend-Filtering dient nur der UX.
| Stufe | Wert | Auf Red gemappt |
|---|---|---|
authenticated |
0 | Via Discord OAuth2 eingeloggt |
guild_member |
1 | Mitglied der Gilde |
guild_mod |
2 | Reds Mod-Rolle (bot.is_mod) |
guild_admin |
3 | Reds Admin-Rolle oder Discord-manage_guild
|
guild_owner |
4 | guild.owner_id == user.id |
bot_owner |
5 | bot.is_owner(user) |
Die Stufen sind kumulativ: Eine höhere Stufe erfüllt jede niedrigere Anforderung. Das Mapping liegt in der permissions.py des Cogs.
Geheimnisse hier ─┐
▼
Browser ──OAuth2──▶ BFF (SvelteKit-Server) ──Token──▶ Gateway (localhost) ──▶ Red-Bot
Cookie (HMAC) DISCORD_CLIENT_SECRET compare_digest is_owner / is_admin / …
GATEWAY_TOKEN Permission-Recheck
SESSION_SECRET
- Discord-Client-Secret, Gateway-Token und Session-Secret liegen nur im BFF.
- Der Browser hält nur ein signiertes Cookie – kein nutzbares Geheimnis.
- Berechtigungen werden am Bot erzwungen, nicht dem Frontend geglaubt.
-
Konfiguration –
SESSION_SECRET,GATEWAY_TOKENund die OAuth2-Variablen - API & Gateway – wie der BFF das Gateway aufruft und wo Rechte geprüft werden
- Architektur – das BFF-Muster im Detail
🇬🇧 English
Users
- Getting Started
- Configuration
- Authentication
- Web UI
- Feature Catalog
- Embed Builder
- Public Pages
- Cog Management
- Statistics
- Logs
- Custom Pages
- Deployment
- Self-Update
Developers