DIY: Auth in Next.js – weniger Magie, mehr Kontrolle

In meiner Zeit als Java-Entwickler (ja, ich hab's getan – Java! 🙈), insbesondere mit Spring Boot, war die Welt der Authentifizierung einfach. Zwei Zeilen im application.yaml
– und zagg-💥, ein sicherer Login stand.
Die Libs waren ausgereift und sicher und so vorkonfiguriert, dass man eigentlich nichts falsch machen konnte. Ein ungeschriebenes Gesetz von mir lautetet damals:
«Auth baut man nicht selbst.»Good old Java Developer
Punkt.
Doch die Realität moderner Webanwendungen, insbesondere im Next.js-Kosmos mit der ganzen Palette von Server-Side Rendering über Streaming von Komponenten bis zu API Endpunkten, ist eine andere. Hier geht es um komplexe Frontends, massgeschneiderte User Experience und spezifische Anforderungen, die oft über das hinausgehen, was All-in-One-Lösungen standardmässig bieten. Und genau hier bin ich an einen Punkt gekommen, wo sich meine Perspektive geändert hat.
Nicht, weil Security plötzlich einfach wäre. Sondern weil in modernen Next.js-Projekten Customizing wichtiger ist als ein starrer "One-size-fits-all"-Ansatz. Wenn du Auth wirklich verstehen und steuern willst, führt heute kein Weg mehr an einem eigenen Setup vorbei.
🤔 Wer sich jetzt fragt: "Wow cool, dann darf ich jetzt also alles selbst bauen – inklusive Benutzername/Passwort Verwaltung etc?"

❌ Auf keinen Fall! Eigene Passwort-Logins zu bauen ist immer noch absolut Tabu!!!iii!! 🙅 Dafür gibt’s ausgereifte Lösungen wie Zitadel oder diverse Social-Login-Provider. Mir geht’s hier nur um die OIDC-Integration.
Wenn dein Auth-Flow nicht Standard ist
Moderne Web-Apps haben oft komplexe Anforderungen an Auth:
- Individuelle User-/Session-Modelle
- Externe Anbieter mit leicht abweichendem Verhalten
- Serverseitige Kontrolle über Sessions
- UX ohne „Login-Flicker“ bei Refresh
- Unterstützung von Backchannel Logout
Tools wie NextAuth (oder neu mit v5 Auth.js, welches schon seeeehr lange Beta ist) waren dafür nie gemacht. Sie sind super für den schnellen Einstieg (#prototyping) – aber wenn du 80 % deines Auth-Flows danach patchen musst, kannst du es auch gleich richtig machen.
Genau da setzte die Auth-Library Lucia an – eine sehr simple Auth-Library, die ich sogar in einem Blogpost vorgestellt habe. Leider ist Lucia inzwischen deprecated. ⚰️🥲
Aber der spannende Punkt ist: Das kleine bisschen, das Lucia abgenommen hat – im Wesentlichen das Zusammenstöpseln der unteren Bausteine – lässt sich auch problemlos selbst umsetzen. Und zwar so, dass man noch flexibler ist und die sicherheitskritischen Teile trotzdem ausgereiften Libraries überlässt.
Und so bin ich heute an einem Punkt, wo ich sage: Ja, man kann OIDC auch selbst machen – und das sogar richtig gut
Was ein stabiler, sicherer OIDC-Flow in Next.js wirklich braucht
🧊 1. Arctic – OIDC wie es sein sollte
Arctic kümmert sich um das, was OIDC am komplexesten macht:
- PKCE und State-Handling
- Login-URLs generieren
- Code austauschen gegen Token
- Multi-Provider-Unterstützung
Und das alles ohne dir vorzuschreiben, wie du deine Session speicherst oder wie dein User-Modell aussehen soll.
🧪 2. Oslo – JWTs & Hashes ohne Bloat
Oslo liefert genau das, was man für Security auf Node-Seite braucht:
- JWT verifizieren (z. B. ID-Tokens vom Provider)
- Hashes für Secrets, Passwörter, Refresh-Token-Keys etc.
- CSRF-Tokens generieren
Dabei bleibt Oslo bewusst klein und unaufgeregt. Perfekt für eigene Auth-Backends.
🧠 3. Redis – Sessions, wie sie sein sollten
Session Handling ist oft der wackeligste Teil in Web-Apps. Viele setzen auf verschlüsselte JWTs als Session-Token – aber das hat Tücken:
- Kein serverseitiges Invalidieren
- Kein einfaches TTL-Handling
- Kein Logout ohne Token-Blacklisting
- Probleme mit Refresh Tokens (Cookie Update in Next.js nicht immer möglich)
Mit Redis kannst du Sessions richtig abbilden:
- Token referenziert Session-ID
- Session ist serverseitig gespeichert und steuerbar
- Nutzer- und Sessiondaten klar getrennt
- Am besten noch serverseitig verschlüsselt
👉 Redis ist hier mein Favorit, aber letztlich kann man jede schnelle, zuverlässige Datenbank verwenden. Wichtig ist nur, dass Sessions serverseitig gespeichert und zentral steuerbar bleiben.
🔁 4. Refresh Tokens – für sanfte UX ohne Security-Kompromisse
Statt das Access Token ewig gültig zu halten, ist es ein Muss auf kurzlebige Tokens plus Refresh Flow zu setzen. Das bringt:
- Sicherheit (Token Diebstahl wird schnell irrelevant)
- UX (kein Login-Flicker, keine harten Redirects)
- Kontrolle (Refresh nur serverseitig erlaubt)
Der Refresh Flow läuft voll backendseitig.
🚪 5. Backchannel Logout – wenn’s dein Provider hergibt
Backchannel Logout ist die sauberste Methode, Sessions zentral zu beenden. Wird z. B. ein Nutzer im zentralen SSO-System ausgeloggt, kann der OIDC-Provider einen Logout-Hook an dein Backend schicken – und du killst die Session direkt in Redis.
Kein Polling. Kein clientseitiger Check mehr nötig.
🔒 6. Backend-for-Frontend (BFF) – für maximale Kontrolle
Ein dediziertes Backend-for-Frontend (BFF) sorgt dafür, dass Access Tokens nie im Client landen – kein localStorage, kein Risiko durch XSS. Wenn die Session auf dem Server ausläuft oder aktiv beendet wird, kann der Client nichts mehr tun – kein Flicker, kein Pseudo-Cleanup.
Das BFF wird damit zur zentralen Instanz für Login, Refresh, Logout und User-Daten – und macht deinen Auth-Flow sicher, robust und übersichtlich. Und falls du bis hier gelesen hast: Respekt! 🎉
Fazit: Auth ist kein Hexenwerk – wenn man weiss, was man tut
Ich dachte lange, Auth sei ein Mienenfeld, das man besser nicht selbst betritt. Heute sehe ich es anders: Wenn du verstehst, was du brauchst – und weisst, was du tust – kannst und solltest du dir mit Arctic, Oslo & Redis einen Auth-Flow bauen, der sicherer, flexibler und langfristig wartbarer ist als viele All-in-One-Lösungen.
Und das Beste: Du hast die volle Kontrolle.
Keine „magischen Defaults“. Keine Library-Blackbox. Sondern Auth, wie sie zu deiner App passt.
Weiterführende Links
- Arctic – Minimalistische OIDC-Client-Library
- Oslo – JWT, Hashes & CSRF für Node.js
- OIDC-Spezifikation (openid.net)
- Backchannel Logout Spezifikation
- Smartive Blogpost zu Lucia Auth
- Blogpost zu Backend For Frontend Pattern
PS: Die Dokumentation von Arctic und Oslo ist super, schau dort unbedingt auch mal rein.

Geschrieben von
Lorenz Bösch