Single Sign-On: der Bot als Identity-Provider für die anderen Dienste

Andere Apps (Kanban, Platform …) nutzen ab sofort den Discord-Login des
Bots mit, statt jeweils eigenes OAuth zu bauen — und bekommen die
Discord-Rollen des Users gleich mitgeliefert.

Ablauf: App leitet auf /sso/authorize weiter, der Bot prüft die Session
(ggf. erst Discord-Login) und schickt einen signierten Token zurück, den
die App serverseitig per POST /sso/verify gegen die Nutzerdaten tauscht.

Sicherheit:
- Rücksprung-Ziele müssen einem registrierten Präfix entsprechen
  (kein Open Redirect, kein Token-Abgriff über fremde Hosts)
- Token HMAC-signiert, 60 Sekunden gültig, nur einmal einlösbar
- Verify braucht das App-Secret (timing-safe verglichen)
- SSO bleibt Mitgliedern des Discord-Servers vorbehalten
- App-Verwaltung ist Owner-only, Secret wird nur einmal angezeigt

Dazu: sso_apps-Tabelle, Verwaltung im API-Tab, Rücksprung nach dem
Login (return-Cookie, nur interne Pfade), Anleitung in docs/sso.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 13:24:03 +02:00
co-authored by Claude Fable 5
parent 8853bce2ec
commit 70cae85064
8 changed files with 413 additions and 2 deletions
+5 -1
View File
@@ -105,12 +105,16 @@ export function registerAuthRoutes(app, client) {
? `https://cdn.discordapp.com/avatars/${me.id}/${me.avatar}.png?size=64`
: null,
};
// Kam der Login über /sso/authorize? Dann dorthin zurück statt auf die Startseite
const { takeReturnTo } = await import('./sso.js');
const returnTo = takeReturnTo(request, reply);
return reply
.clearCookie(STATE_COOKIE, { path: '/auth' })
.setCookie(SESSION_COOKIE, JSON.stringify(session), {
path: '/', httpOnly: true, sameSite: 'lax', maxAge: 7 * 24 * 3600, signed: true,
})
.redirect('/');
.redirect(returnTo ?? '/');
});
app.get('/auth/logout', async (request, reply) => {