Mitglieder-Authentifizierung
Authentifiziere Site-Mitglieder mit sicheren httpOnly-Cookie-Sessions - Anmeldung, Registrierung, Passwort-Reset, Auslesen des aktuellen Mitglieds und Nutzung von Auth aus einem Block.
Überblick
Site-Mitglieder sind die Endnutzer deiner veröffentlichten Website - komplett getrennt von CMS-Admin-Nutzern. Jeder Workspace hat seine eigene Mitgliederbasis (multi-tenant). Das SDK stellt Mitglieder-Sessions als httpOnly-Cookies aus (cmssy_session, ein versiegeltes JWE), sodass der Token nie aus JavaScript lesbar ist und nie deinen Client-Code berührt. Das SDK übernimmt Versiegelung, Refresh und den Authorization: Bearer-Austausch serverseitig.
1. Konfigurieren
Füge deiner Konfiguration einen auth-Block hinzu. Er ist optional - lässt du ihn weg, ist Member-Auth einfach aus (context.auth ist undefined und Blöcke rendern ausgeloggt).
// cmssy.config.ts
export const cmssy: CmssyNextConfig = {
// ...
auth: {
modelSlug: "members", // the member model in your workspace
sessionSecret: process.env.CMSSY_SESSION_SECRET!, // >= 32 chars
},
};2. Die Auth-Route einbinden
Ein einziger Route-Handler treibt den gesamten Flow an. Zugangsdaten und Tokens werden nur hier verarbeitet, serverseitig - Clients senden nur POSTs.
// app/api/auth/[action]/route.ts
import { createCmssyAuthRoute } from "@cmssy/next";
import { cmssy } from "@/cmssy.config";
export const { POST, GET } = createCmssyAuthRoute(cmssy);| Methode + Aktion | Body | Effekt |
|---|---|---|
POST /api/auth/sign-in | { identity, password } | Setzt das Session-Cookie. |
POST /api/auth/register | { identity, password, fields } | Erstellt ein Mitglied. |
POST /api/auth/sign-out | - | Löscht die Session. |
POST /api/auth/sign-out-everywhere | - | Widerruft alle Sessions. |
POST /api/auth/refresh | - | Rotiert die Tokens. |
POST /api/auth/forgot-password | { identity } | Sendet eine Reset-E-Mail. |
POST /api/auth/reset-password | { token, newPassword } | Setzt ein Passwort zurück. |
POST /api/auth/verify-email | { token } | Verifiziert eine E-Mail. |
GET /api/auth/me | - | Gibt { user } oder { user: null } zurück. |
Jede Aktion gibt JSON { ok: boolean, message?, user? } zurück.
3. Sessions in der Middleware auffrischen
// middleware.ts
import { createCmssyAuthMiddleware } from "@cmssy/next";
import { cmssy } from "@/cmssy.config";
export const middleware = createCmssyAuthMiddleware(cmssy);Das erneuert ein ablaufendes Session-Cookie transparent bei der Navigation, sodass Mitglieder angemeldet bleiben - ganz ohne clientseitiges Token-Handling.
4. Client-Auth-Flow
Deine Login-, Registrierungs- und Logout-UI sind gewöhnliche Client-Komponenten, die per POST an die Route senden. Sie sehen nie einen Token - die Route setzt das Cookie.
"use client";
// sign in
await fetch("/api/auth/sign-in", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ identity: email, password }),
});
// the route set the cookie - now redirect
window.location.href = "/";
// log out
await fetch("/api/auth/sign-out", { method: "POST" });Baue dedizierte Seiten für den Flow: /login, /register, /forgot-password, /reset-password, /verify-email. Jede ist eine kleine Client-Komponente, die an /api/auth/* POSTet und dann weiterleitet.
5. Aktuelles Mitglied auslesen (serverseitig)
import { getCmssyUser, getCmssyAccessToken } from "@cmssy/next";
import { cmssy } from "@/cmssy.config";
const user = await getCmssyUser(cmssy); // { recordId, email } | null
const token = await getCmssyAccessToken(cmssy); // bearer token | null6. Auth innerhalb eines Blocks lesen
Wenn config.auth gesetzt ist, löst createCmssyPage das Mitglied serverseitig auf und injiziert es als context.auth in den Block-Context - nur Daten:
context.auth;
// { isAuthenticated: boolean; member: { recordId, email } | null } | undefinedimport type { CmssyBlockAuthContext } from "@cmssy/react";
function AccountBadge({ context }: { context?: { auth?: CmssyBlockAuthContext } }) {
if (!context?.auth?.isAuthenticated) return <a href="/login">Sign in</a>;
return <span>{context.auth.member?.email}</span>;
}Es gibt keine login/logout-Funktionen auf context.auth - Funktionen können die Server-zu-Client-Grenze in einen Client-Block nicht überqueren. Anmelden, Abmelden und Registrieren laufen über die Client-POSTs aus Schritt 4.
7. Authentifizierte Mitglieder-Requests
Eine Member-scoped Mutation (z. B. ein Profil-Update) braucht den Access-Token, der im httpOnly-Cookie lebt und aus Client-JS bewusst nicht lesbar ist. Versuch nicht, ihn clientseitig anzuhängen. Rufe sie aus einem Route-Handler oder einer Server Action auf, die den Token liest und als Authorization: Bearer weiterreicht:
// app/api/member-graphql/route.ts
import { getCmssyAccessToken } from "@cmssy/next";
import { cmssy } from "@/cmssy.config";
export async function POST(request: Request) {
const token = await getCmssyAccessToken(cmssy);
if (!token) {
return Response.json({ errors: [{ message: "Not authenticated" }] }, { status: 401 });
}
const upstream = await fetch(cmssy.apiUrl, {
method: "POST",
headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
body: JSON.stringify(await request.json()),
});
return Response.json(await upstream.json(), { status: upstream.status });
}Dein Client-Block sendet Member-Mutationen dann per POST an /api/member-graphql statt an den öffentlichen Endpoint, und der Token erreicht nie den Browser.
Anti-Pattern
// DON'T - XSS-readable, and bypasses the secure cookie flow entirely
localStorage.setItem("member_token", accessToken);Geh immer über createCmssyAuthRoute + das httpOnly-Cookie.
Mitgliederrollen
Standardrollen: Guest, Member (wird bei der Registrierung zugewiesen), Premium. Eigene Rollen sind pro Workspace konfigurierbar.
E-Mail-Verifizierungs-Flow
- Registrieren -> Status pending, eine Verifizierungs-E-Mail wird gesendet.
- Link klicken ->
/verify-email?token=...-> Status active. - Wenn E-Mail-Verifizierung erforderlich ist, ist die Anmeldung blockiert, bis das Mitglied verifiziert ist.
Passwort-Reset-Flow
- Passwort-vergessen-Formular -> eine Reset-E-Mail wird gesendet.
- Link klicken ->
/reset-password?token=...-> neues Passwort setzen. - Reset-Tokens laufen nach 1 Stunde ab.
Sessions
Die Session ist ein versiegeltes JWE im httpOnly-Cookie cmssy_session. Die Middleware rotiert sie transparent, wenn sie sich dem Ablauf nähert - dein Code liest oder erneuert nie einen Token von Hand. Alle Mitgliederdaten sind workspace-scoped (multi-tenant-sicher).