EmDash verwendet Passkey-Authentifizierung als primäre Anmeldemethode. Passkeys sind phishing-resistent, erfordern keine Passwörter und funktionieren geräteübergreifend über Ihren Browser oder Passwort-Manager.
Über Passkeys hinaus können Sie austauschbare Login-Anbieter hinzufügen — GitHub, Google und die Atmosphere (AT Protocol) werden direkt mitgeliefert, und die gleiche Anbieter-Schnittstelle steht für Drittanbieter-Pakete offen. Jeder konfigurierte Anbieter kann verwendet werden, um das erste Admin-Konto zu erstellen, sich anzumelden oder mit einem bestehenden Benutzer zu verknüpfen.
Für Cloudflare-Bereitstellungen ist Cloudflare Access auch als exklusive Authentifizierungsmethode verfügbar, die den gesamten Login-Ablauf übernimmt.
Wie es funktioniert
Passkeys verwenden WebAuthn, einen Webstandard, der Public-Key-Anmeldeinformationen erstellt, die auf Ihrem Gerät gespeichert oder über Ihren Passwort-Manager synchronisiert werden. Wenn Sie sich anmelden, beweist Ihr Gerät den Besitz der Anmeldeinformationen, ohne jemals ein Passwort über das Netzwerk zu senden.
Vorteile der Passkey-Authentifizierung:
- Keine Passwörter zum Merken oder Verlieren
- Phishing-resistent — Anmeldeinformationen sind an die Domain Ihrer Website gebunden
- Geräteübergreifende Synchronisierung — funktioniert mit iCloud-Schlüsselbund, Google Passwort-Manager, 1Password usw.
- Schnelle Anmeldung — ein Tippen mit Biometrie oder PIN
Erste Benutzereinrichtung
Beim ersten Zugriff auf das Admin-Panel führt Sie der Setup-Assistent durch die Erstellung Ihres Admin-Kontos.
-
Navigieren Sie zu
http://localhost:4321/_emdash/admin -
Sie werden zum Setup-Assistenten weitergeleitet. Geben Sie ein:
- Site-Titel — Der Name Ihrer Website
- Tagline — Eine kurze Beschreibung
- Admin-E-Mail — Ihre E-Mail-Adresse
-
Klicken Sie auf Site erstellen, um Ihren Passkey zu registrieren
-
Ihr Browser fordert Sie auf, einen Passkey zu erstellen:
- Auf macOS: Touch ID, Gerätepasswort oder Sicherheitsschlüssel
- Auf Windows: Windows Hello oder Sicherheitsschlüssel
- Auf Mobilgeräten: Face ID, Fingerabdruck oder PIN
-
Sobald Ihr Passkey registriert ist, sind Sie angemeldet und werden zum Admin-Dashboard weitergeleitet.
Anmeldung
Nach der Einrichtung löst die Rückkehr zum Admin-Panel die Passkey-Authentifizierung aus:
-
Besuchen Sie
/_emdash/admin -
Wenn Sie nicht angemeldet sind, sehen Sie die Anmeldeseite
-
Klicken Sie auf Anmelden, um sich zu authentifizieren
-
Ihr Browser fordert Ihren Passkey an (Biometrie, PIN oder Sicherheitsschlüssel)
-
Nach der Verifizierung werden Sie zum Admin-Dashboard weitergeleitet
Magic-Link-Fallback
Wenn Sie Ihren Passkey nicht verwenden können (z.B. verlorenes Gerät), bieten Magic-Links eine Alternative. Dies erfordert eine konfigurierte E-Mail.
-
Klicken Sie auf der Anmeldeseite auf Mit E-Mail anmelden
-
Geben Sie Ihre E-Mail-Adresse ein
-
Überprüfen Sie Ihren Posteingang auf einen Anmeldelink
-
Klicken Sie auf den Link, um sich zu authentifizieren (15 Minuten gültig)
Login-Anbieter
Zusätzlich zu Passkeys unterstützt EmDash austauschbare Login-Anbieter, die auf der Anmeldeseite und im Setup-Assistenten erscheinen. GitHub-, Google- und Atmosphere-Anbieter werden mitgeliefert; Drittanbieter-Pakete können ihre eigenen über die gleiche Schnittstelle registrieren.
Anbieter sind additiv — Passkeys funktionieren weiterhin, wenn Anbieter aktiviert sind, und Benutzer können einen Anbieter mit einem bestehenden Nur-Passkey-Konto verknüpfen. Der erste Benutzer kann auch über jeden konfigurierten Anbieter erstellt werden, sodass eine Neuinstallation Passkeys vollständig überspringen kann, wenn Sie das bevorzugen.
Anbieter konfigurieren
Übergeben Sie Anbieter an das authProviders-Array in der EmDash-Integration. Das folgende Beispiel aktiviert GitHub, Google und Atmosphere:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { github } from "emdash/auth/providers/github";
import { google } from "emdash/auth/providers/google";
import { atproto } from "@emdash-cms/auth-atproto";
export default defineConfig({
integrations: [
emdash({
authProviders: [github(), google(), atproto()],
}),
],
});
Die Reihenfolge ist wichtig für die Anmeldeseite: Anbieter werden in der von Ihnen angegebenen Reihenfolge gerendert, wobei kompakte Nur-Button-Anbieter zuerst und Anbieter, die ein benutzerdefiniertes Formular benötigen (wie Atmosphere, das nach einem Handle fragt), danach angezeigt werden.
GitHub
Das folgende Beispiel aktiviert den GitHub-Anbieter:
import { github } from "emdash/auth/providers/github";
emdash({ authProviders: [github()] });
Setzen Sie Anmeldeinformationen über Umgebungsvariablen. EmDash prüft zuerst die präfixierten Namen und greift auf die unpräfixierten zurück:
| Variable | Zweck |
|---|---|
EMDASH_OAUTH_GITHUB_CLIENT_ID / GITHUB_CLIENT_ID | OAuth-App-Client-ID |
EMDASH_OAUTH_GITHUB_CLIENT_SECRET / GITHUB_CLIENT_SECRET | OAuth-App-Geheimnis |
Konfigurieren Sie die Callback-URL Ihrer GitHub-OAuth-App als https://your-site.example.com/_emdash/api/auth/oauth/github/callback.
Das folgende Beispiel aktiviert den Google-Anbieter:
import { google } from "emdash/auth/providers/google";
emdash({ authProviders: [google()] });
Setzen Sie Anmeldeinformationen über Umgebungsvariablen. EmDash prüft zuerst die präfixierten Namen und greift auf die unpräfixierten zurück:
| Variable | Zweck |
|---|---|
EMDASH_OAUTH_GOOGLE_CLIENT_ID / GOOGLE_CLIENT_ID | OAuth-App-Client-ID |
EMDASH_OAUTH_GOOGLE_CLIENT_SECRET / GOOGLE_CLIENT_SECRET | OAuth-App-Geheimnis |
Konfigurieren Sie die Redirect-URI Ihres Google-OAuth-Clients als https://your-site.example.com/_emdash/api/auth/oauth/google/callback.
Atmosphere (AT Protocol)
Für Websites, bei denen Mitwirkende bereits ein Atmosphere-Konto haben — die benutzereigene Identität hinter Bluesky und dem breiteren AT-Protocol-Netzwerk — installieren Sie den Atmosphere-Anbieter:
pnpm add @emdash-cms/auth-atproto
Das folgende Beispiel aktiviert den Atmosphere-Anbieter mit einer Handle-Zulassungsliste:
import { atproto } from "@emdash-cms/auth-atproto";
emdash({
authProviders: [
atproto({
allowedHandles: ["*.example.com"],
}),
],
});
Kein Client-Geheimnis oder Umgebungsvariable ist erforderlich. Siehe die Atmosphere-Login-Anleitung für Handle/DID-Zulassungslisten, Rollenzuordnung und die lokale Entwicklungseinrichtung, die das AT-Protocol-OAuth-Profil erfordert.
Einen eigenen Anbieter erstellen
Ein Anbieter ist nur ein AuthProviderDescriptor — eine id, ein menschliches Label und jede Kombination aus Admin-seitigen React-Komponenten, Route-Handlern, öffentlichen Route-Präfixen und Speichersammlungen. Die Form wird aus emdash exportiert:
import type { AuthProviderDescriptor } from "emdash";
export function myProvider(): AuthProviderDescriptor {
return {
id: "my-provider",
label: "My Provider",
adminEntry: "my-provider/admin", // exports LoginButton / LoginForm / SetupStep
routes: [
{ pattern: "/_emdash/api/auth/my-provider/login", entrypoint: "my-provider/routes/login.ts" },
{ pattern: "/_emdash/api/auth/my-provider/callback", entrypoint: "my-provider/routes/callback.ts" },
],
publicRoutes: ["/_emdash/api/auth/my-provider/"],
storage: {
sessions: {},
},
};
}
Das Atmosphere-Paket (@emdash-cms/auth-atproto) ist die vollständigste reale Referenz für einen Anbieter, der ein benutzerdefiniertes Anmeldeformular, OAuth-Route-Handler und persistenten Speicher benötigt.
Benutzerrollen
EmDash verwendet rollenbasierte Zugriffskontrolle mit fünf Ebenen:
| Rolle | Ebene | Beschreibung |
|---|---|---|
| Subscriber | 10 | Veröffentlichte Inhalte lesen (kein Entwurfszugriff) |
| Contributor | 20 | Inhalte erstellen (benötigt Genehmigung zum Veröffentlichen) |
| Author | 30 | Eigene Inhalte erstellen/bearbeiten/veröffentlichen |
| Editor | 40 | Alle Inhalte verwalten |
| Admin | 50 | Vollzugriff einschließlich Einstellungen |
Jede Rolle erbt Berechtigungen von allen niedrigeren Ebenen. Der erste Benutzer wird immer als Admin erstellt.
Abonnenten und Entwurfsinhalte
Abonnenten haben die content:read-Berechtigung, sodass nur für Mitglieder bestimmte veröffentlichte Inhalte an authentifizierte Leser ausgeliefert werden können. Sie können keine Entwürfe, geplante Elemente, in den Papierkorb verschobene Elemente, Revisionen oder Vorschau-URLs sehen — diese sind durch content:read_drafts geschützt, das Contributors und höher gewährt wird. Die Listen- und Abruf-Endpunkte filtern transparent auf status=published für Abonnenten; Nur-Editor-Ansichten (/compare, /revisions, /trash, /preview-url) lehnen Abonnenten-Anfragen vollständig ab.
Benutzer einladen
Administratoren können neue Benutzer über das Admin-Panel einladen:
-
Gehen Sie zu Einstellungen > Benutzer
-
Klicken Sie auf Benutzer einladen
-
Geben Sie die E-Mail des Benutzers ein und wählen Sie eine Rolle
-
Klicken Sie auf Einladung senden
-
Der Benutzer erhält eine E-Mail mit einem Einladungslink
-
Er klickt auf den Link und registriert seinen Passkey
Einladungen sind 7 Tage gültig. Administratoren können Einladungen von der Benutzerseite aus erneut senden oder widerrufen.
Passkeys verwalten
Benutzer können ihre Passkeys in den Kontoeinstellungen verwalten:
- Passkey hinzufügen — Zusätzliche Passkeys für Backup oder andere Geräte registrieren
- Passkey entfernen — Passkeys löschen, die Sie nicht mehr verwenden
- Passkey umbenennen — Passkeys beschreibende Namen geben
Jeder Benutzer kann bis zu 10 Passkeys registrieren.
Eine Gruppe ohne Einladungen anmelden lassen
Um einer Gruppe die Anmeldung zu ermöglichen, ohne jeden Benutzer einzuladen, konfigurieren Sie einen Login-Anbieter mit einer Zulassungsliste. Der Atmosphere-Anbieter akzeptiert allowedHandles und allowedDIDs (siehe Atmosphere-Login); der Cloudflare Access-Adapter stellt Benutzer von Ihrem Identitätsanbieter über autoProvision und roleMapping bereit. Jeder konfigurierte Anbieter kann auch das erste Admin-Konto erstellen.
Sitzungen
Sitzungen verwenden sichere, HttpOnly, SameSite=Lax-Cookies und dauern 30 Tage mit gleitender Ablaufzeit — die Ablaufzeit wird bei Aktivität zurückgesetzt.
Sicherheitshinweise
- Passkeys werden als öffentliche Schlüssel gespeichert — der private Schlüssel verlässt niemals Ihr Gerät
- Challenge-Verifizierung verhindert Replay-Angriffe
- Rate Limiting schützt vor Brute-Force-Angriffen (5 Versuche/Minute/IP)
- Sitzungen sind HttpOnly, Secure, SameSite=Lax für Cookie-Sicherheit
- Magic-Link-Tokens werden SHA-256-gehasht — rohe Tokens werden niemals gespeichert
Fehlerbehebung
”Keine Passkeys registriert”
Wenn Sie diesen Fehler bei der Anmeldung sehen, wurde Ihr Passkey möglicherweise aus Ihrem Passwort-Manager gelöscht. Bitten Sie einen Administrator, Ihnen einen Magic-Link oder eine neue Einladung zu senden.
”Passkey-Authentifizierung fehlgeschlagen”
Dies bedeutet normalerweise, dass der Passkey für eine andere Domain erstellt wurde. Passkeys sind domänengebunden — ein Passkey für localhost:4321 funktioniert nicht auf example.com. Registrieren Sie einen neuen Passkey für jede Domain.
”Sitzung abgelaufen”
Sitzungen dauern standardmäßig 30 Tage mit gleitender Ablaufzeit. Wenn Sie unerwartet abgemeldet werden, löschen Sie Ihre Cookies und melden Sie sich erneut an.
Alle Passkeys verloren
Wenn Sie den Zugriff auf alle Ihre registrierten Passkeys verloren haben:
- Bitten Sie einen anderen Administrator, Ihnen einen Magic-Link zu senden (erfordert E-Mail-Konfiguration)
- Verwenden Sie den Magic-Link, um sich anzumelden
- Registrieren Sie einen neuen Passkey in den Kontoeinstellungen
Wenn Sie der einzige Administrator sind und E-Mail nicht konfiguriert ist, müssen Sie die Authentifizierung Ihrer Website über die Datenbank zurücksetzen.
Cloudflare Access
Bei der Bereitstellung auf Cloudflare können Sie Cloudflare Access als Ihren Authentifizierungsanbieter anstelle von Passkeys verwenden. Access verarbeitet die Authentifizierung am Edge unter Verwendung Ihres bestehenden Identitätsanbieters.
Warum Cloudflare Access verwenden
- Single Sign-On — Benutzer authentifizieren sich mit dem IdP Ihres Unternehmens
- Zentrale Zugriffskontrolle — Verwalten Sie, wer auf das Admin im Cloudflare-Dashboard zugreifen kann
- Keine Passkey-Verwaltung — Keine Notwendigkeit, Passkeys zu registrieren oder zu verwalten
- Gruppenbasierte Rollen — Ordnen Sie IdP-Gruppen automatisch EmDash-Rollen zu
Einrichtung
- Erstellen Sie eine Cloudflare Access-Anwendung für Ihre EmDash-Website
- Notieren Sie das Application Audience (AUD) Tag aus den Anwendungseinstellungen
- Konfigurieren Sie EmDash zur Verwendung von Access:
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import emdash from "emdash/astro";
import { d1, access } from "@emdash-cms/cloudflare";
export default defineConfig({
output: "server",
adapter: cloudflare(),
integrations: [
emdash({
database: d1({ binding: "DB" }),
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "abc123def456...", // From Access app settings
}),
}),
],
});
Konfigurationsoptionen
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
teamDomain | string | erforderlich | Ihre Access-Team-Domain (z.B. myteam.cloudflareaccess.com) |
audience | string | erforderlich | Application Audience (AUD) Tag aus Access-Einstellungen |
autoProvision | boolean | true | EmDash-Benutzer bei erster Access-Anmeldung erstellen |
defaultRole | number | 30 | Rolle für Benutzer, die keiner Gruppe entsprechen (30 = Author) |
syncRoles | boolean | false | Rolle bei jeder Anmeldung basierend auf IdP-Gruppen aktualisieren |
roleMapping | object | — | IdP-Gruppennamen Rollenebenen zuordnen |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | Name der Umgebungsvariablen für das Audience-Tag (Alternative zur Hardcodierung) |
Rollenzuordnung
Ordnen Sie Ihre IdP-Gruppen EmDash-Rollen zu:
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "abc123...",
roleMapping: {
Admins: 50, // Admin
"Content Editors": 40, // Editor
Writers: 30, // Author
},
defaultRole: 20, // Contributor für Benutzer, die in keiner Gruppe sind
}),
});
Die erste übereinstimmende Gruppe gewinnt, wenn ein Benutzer mehreren Gruppen angehört. Der erste Benutzer, der auf die Website zugreift, wird unabhängig von Gruppen immer Admin.
Rollensynchronisierungsverhalten
Standardmäßig (syncRoles: false) wird die Rolle eines Benutzers festgelegt, wenn er sich zum ersten Mal anmeldet, und ändert sich danach nicht. Dies ermöglicht es Administratoren, Rollen in EmDash manuell anzupassen.
Setzen Sie syncRoles: true, wenn Sie möchten, dass IdP-Gruppen maßgeblich sind — die Rolle des Benutzers wird bei jeder Anmeldung basierend auf seinen aktuellen Gruppen aktualisiert.
Wie es funktioniert
- Benutzer besucht
/_emdash/admin - Cloudflare Access fängt ab und leitet zu Ihrem IdP weiter
- Benutzer authentifiziert sich (SSO, MFA usw.)
- Access setzt ein signiertes JWT in die Anfrage
- EmDash validiert das JWT und erstellt/authentifiziert den Benutzer
Deaktivierte Funktionen
Wenn Access aktiviert ist, sind diese Funktionen nicht verfügbar:
- Anmeldeseite (
/_emdash/admin/login) - Passkey-Registrierung und -Verwaltung
- OAuth-Anmeldung
- Magic-Link-Anmeldung
- Selbstregistrierung
- Benutzereinladungen
Die Benutzerverwaltung erfolgt vollständig über Ihre Cloudflare Access-Richtlinien.
Fehlerbehebung
”Kein Access JWT vorhanden”
Die Anfrage erreichte EmDash ohne Access JWT. Dies bedeutet:
- Access ist nicht konfiguriert, um Ihre Anwendung zu schützen
- Die Access-Richtlinie entspricht nicht den Admin-Routen
Überprüfen Sie, ob Ihre Access-Anwendung /_emdash/admin/* abdeckt.
”JWT-Audience-Nichtübereinstimmung”
Die audience in Ihrer Konfiguration stimmt nicht mit dem JWT überein. Überprüfen Sie das Application Audience Tag in Ihren Access-Anwendungseinstellungen.
”Benutzer nicht autorisiert”
Der Benutzer hat sich über Access authentifiziert, aber autoProvision ist false und er existiert nicht in EmDash. Entweder:
- Setzen Sie
autoProvision: true, oder - Erstellen Sie den Benutzer manuell, bevor er sich anmeldet