EmDash utilizza l’autenticazione passkey come metodo di accesso principale. Le passkey sono resistenti al phishing, non richiedono password e funzionano su tutti i dispositivi tramite il browser o il gestore di password.
Oltre alle passkey, puoi aggiungere provider di accesso plug-in — GitHub, Google e Atmosphere (AT Protocol) sono inclusi nella confezione e la stessa interfaccia provider è aperta per pacchetti di terze parti. Qualsiasi provider configurato può essere utilizzato per creare il primo account amministratore, effettuare l’accesso o collegarsi a un utente esistente.
Per le distribuzioni Cloudflare, Cloudflare Access è disponibile anche come metodo di autenticazione esclusivo che prende il controllo dell’intero flusso di accesso.
Come funziona
Le passkey utilizzano WebAuthn, uno standard web che crea credenziali a chiave pubblica memorizzate sul dispositivo o sincronizzate tramite il gestore di password. Quando effettui l’accesso, il dispositivo dimostra il possesso delle credenziali senza mai inviare una password attraverso la rete.
Vantaggi dell’autenticazione con passkey:
- Nessuna password da ricordare o perdere
- Resistente al phishing — le credenziali sono legate al dominio del tuo sito
- Sincronizzazione tra dispositivi — funziona con iCloud Keychain, Google Password Manager, 1Password, ecc.
- Accesso rapido — un tocco con biometria o PIN
Configurazione del primo utente
La prima volta che accedi al pannello di amministrazione, la Procedura guidata di configurazione ti guida nella creazione del tuo account amministratore.
-
Naviga su
http://localhost:4321/_emdash/admin -
Verrai reindirizzato alla Procedura guidata di configurazione. Inserisci:
- Titolo del sito — Il nome del tuo sito
- Slogan — Una breve descrizione
- Email amministratore — Il tuo indirizzo email
-
Fai clic su Crea sito per registrare la tua passkey
-
Il browser ti chiederà di creare una passkey:
- Su macOS: Touch ID, password del dispositivo o chiave di sicurezza
- Su Windows: Windows Hello o chiave di sicurezza
- Su mobile: Face ID, impronta digitale o PIN
-
Una volta registrata la passkey, sei connesso e reindirizzato al pannello di amministrazione.
Effettuare l’accesso
Dopo la configurazione, tornare al pannello di amministrazione attiva l’autenticazione con passkey:
-
Visita
/_emdash/admin -
Se non hai effettuato l’accesso, vedrai la pagina di accesso
-
Fai clic su Accedi per autenticarti
-
Il browser richiede la tua passkey (biometria, PIN o chiave di sicurezza)
-
Dopo la verifica, vieni reindirizzato al pannello di amministrazione
Link magico come alternativa
Se non puoi utilizzare la tua passkey (ad esempio, dispositivo perso), i link magici forniscono un’alternativa. Questo richiede che l’email sia configurata.
-
Nella pagina di accesso, fai clic su Accedi con email
-
Inserisci il tuo indirizzo email
-
Controlla la tua casella di posta per un link di accesso
-
Fai clic sul link per autenticarti (valido per 15 minuti)
Provider di accesso
Oltre alle passkey, EmDash supporta provider di accesso plug-in che compaiono sulla pagina di accesso e nella procedura guidata di configurazione. I provider GitHub, Google e Atmosphere sono inclusi nella confezione; i pacchetti di terze parti possono registrare i propri utilizzando la stessa interfaccia.
I provider sono additivi: le passkey continuano a funzionare quando i provider sono abilitati e gli utenti possono collegare un provider a un account esistente solo con passkey. Il primo utente può anche essere creato tramite qualsiasi provider configurato, quindi una nuova installazione può saltare completamente le passkey se preferisci.
Configurare i provider
Passa i provider all’array authProviders nell’integrazione EmDash. L’esempio seguente abilita GitHub, Google e 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()],
}),
],
});
L’ordine conta per la pagina di accesso: i provider vengono visualizzati nell’ordine in cui li elenchi, con i provider compatti solo a pulsante prima e i provider che necessitano di un modulo personalizzato (come Atmosphere, che richiede un identificatore) mostrati dopo.
GitHub
L’esempio seguente abilita il provider GitHub:
import { github } from "emdash/auth/providers/github";
emdash({ authProviders: [github()] });
Imposta le credenziali tramite variabili d’ambiente. EmDash controlla prima i nomi con prefisso e ricorre a quelli senza prefisso:
| Variabile | Scopo |
|---|---|
EMDASH_OAUTH_GITHUB_CLIENT_ID / GITHUB_CLIENT_ID | ID client dell’app OAuth |
EMDASH_OAUTH_GITHUB_CLIENT_SECRET / GITHUB_CLIENT_SECRET | Segreto dell’app OAuth |
Configura l’URL di callback della tua app OAuth GitHub come https://your-site.example.com/_emdash/api/auth/oauth/github/callback.
L’esempio seguente abilita il provider Google:
import { google } from "emdash/auth/providers/google";
emdash({ authProviders: [google()] });
Imposta le credenziali tramite variabili d’ambiente. EmDash controlla prima i nomi con prefisso e ricorre a quelli senza prefisso:
| Variabile | Scopo |
|---|---|
EMDASH_OAUTH_GOOGLE_CLIENT_ID / GOOGLE_CLIENT_ID | ID client dell’app OAuth |
EMDASH_OAUTH_GOOGLE_CLIENT_SECRET / GOOGLE_CLIENT_SECRET | Segreto dell’app OAuth |
Configura l’URI di reindirizzamento del tuo client OAuth Google come https://your-site.example.com/_emdash/api/auth/oauth/google/callback.
Atmosphere (AT Protocol)
Per siti in cui i collaboratori hanno già un account Atmosphere — l’identità di proprietà dell’utente dietro Bluesky e la più ampia rete AT Protocol — installa il provider Atmosphere:
pnpm add @emdash-cms/auth-atproto
L’esempio seguente abilita il provider Atmosphere con una lista di identificatori consentiti:
import { atproto } from "@emdash-cms/auth-atproto";
emdash({
authProviders: [
atproto({
allowedHandles: ["*.example.com"],
}),
],
});
Non è necessario alcun segreto client o variabile d’ambiente. Consulta la guida all’accesso Atmosphere per le liste di identificatori/DID consentiti, la mappatura dei ruoli e la configurazione di sviluppo locale richiesta dal profilo OAuth del Protocollo AT.
Creare il proprio provider
Un provider è solo un AuthProviderDescriptor — un id, un’etichetta leggibile e qualsiasi combinazione di componenti React lato amministrazione, gestori di route, prefissi di route pubbliche e collezioni di archiviazione. La forma viene esportata da emdash:
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: {},
},
};
}
Il pacchetto Atmosphere (@emdash-cms/auth-atproto) è il riferimento reale più completo per un provider che necessita di un modulo di accesso personalizzato, gestori di route OAuth e archiviazione persistente.
Ruoli utente
EmDash utilizza il controllo degli accessi basato sui ruoli con cinque livelli:
| Ruolo | Livello | Descrizione |
|---|---|---|
| Subscriber | 10 | Leggere contenuti pubblicati (nessun accesso alle bozze) |
| Contributor | 20 | Creare contenuti (richiede approvazione per pubblicare) |
| Author | 30 | Creare/modificare/pubblicare i propri contenuti |
| Editor | 40 | Gestire tutti i contenuti |
| Admin | 50 | Accesso completo incluse le impostazioni |
Ogni ruolo eredita i permessi da tutti i livelli inferiori. Il primo utente viene sempre creato come Admin.
Abbonati e contenuti bozza
Gli abbonati hanno il permesso content:read in modo che i contenuti pubblicati riservati ai membri possano essere serviti ai lettori autenticati. Non possono vedere bozze, elementi programmati, elementi nel cestino, revisioni o URL di anteprima — questi sono protetti da content:read_drafts, concesso ai Contributor e superiori. Gli endpoint di elenco e recupero filtrano in modo trasparente su status=published per gli Abbonati; le visualizzazioni riservate agli editori (/compare, /revisions, /trash, /preview-url) rifiutano direttamente le richieste degli Abbonati.
Invitare utenti
Gli amministratori possono invitare nuovi utenti tramite il pannello di amministrazione:
-
Vai su Impostazioni > Utenti
-
Fai clic su Invita utente
-
Inserisci l’email dell’utente e seleziona un ruolo
-
Fai clic su Invia invito
-
L’utente riceve un’email con un link di invito
-
Fa clic sul link e registra la sua passkey
Gli inviti sono validi per 7 giorni. Gli amministratori possono reinviare o revocare gli inviti dalla pagina Utenti.
Gestire le passkey
Gli utenti possono gestire le proprie passkey dalle impostazioni dell’account:
- Aggiungi passkey — Registrare passkey aggiuntive per backup o altri dispositivi
- Rimuovi passkey — Eliminare le passkey che non usi più
- Rinomina passkey — Dare nomi descrittivi alle passkey
Ogni utente può avere fino a 10 passkey registrate.
Permettere a un gruppo di accedere senza inviti
Per consentire a un gruppo di accedere senza invitare ogni utente, configura un provider di accesso con una lista consentita. Il provider Atmosphere accetta allowedHandles e allowedDIDs (vedi accesso Atmosphere); l’adattatore Cloudflare Access fornisce utenti dal tuo provider di identità tramite autoProvision e roleMapping. Qualsiasi provider configurato può anche creare l’account amministratore iniziale.
Sessioni
Le sessioni utilizzano cookie sicuri, HttpOnly, SameSite=Lax e durano 30 giorni con scadenza scorrevole — la scadenza si resetta con l’attività.
Note sulla sicurezza
- Le passkey sono archiviate come chiavi pubbliche — la chiave privata non lascia mai il dispositivo
- Verifica della sfida previene attacchi replay
- Limitazione della velocità protegge da attacchi brute force (5 tentativi/minuto/IP)
- Le sessioni sono HttpOnly, Secure, SameSite=Lax per la sicurezza dei cookie
- I token dei link magici sono sottoposti a hash SHA-256 — i token grezzi non vengono mai memorizzati
Risoluzione dei problemi
”Nessuna passkey registrata”
Se vedi questo errore all’accesso, la tua passkey potrebbe essere stata eliminata dal tuo gestore di password. Chiedi a un amministratore di inviarti un link magico o un nuovo invito.
”Autenticazione passkey fallita”
Questo di solito significa che la passkey è stata creata per un dominio diverso. Le passkey sono legate al dominio — una passkey per localhost:4321 non funzionerà su example.com. Registra una nuova passkey per ogni dominio.
”Sessione scaduta”
Le sessioni durano 30 giorni per impostazione predefinita con scadenza scorrevole. Se vieni disconnesso inaspettatamente, cancella i tuoi cookie e accedi di nuovo.
Perso tutte le passkey
Se hai perso l’accesso a tutte le tue passkey registrate:
- Chiedi a un altro amministratore di inviarti un link magico (richiede configurazione email)
- Usa il link magico per accedere
- Registra una nuova passkey nelle impostazioni dell’account
Se sei l’unico amministratore e l’email non è configurata, dovrai reimpostare l’autenticazione del tuo sito tramite il database.
Cloudflare Access
Quando distribuisci su Cloudflare, puoi utilizzare Cloudflare Access come provider di autenticazione invece delle passkey. Access gestisce l’autenticazione sul bordo utilizzando il tuo provider di identità esistente.
Perché utilizzare Cloudflare Access
- Single Sign-On — Gli utenti si autenticano con l’IdP della tua azienda
- Controllo degli accessi centralizzato — Gestisci chi può accedere all’amministrazione nel pannello Cloudflare
- Nessuna gestione di passkey — Non è necessario registrare o gestire passkey
- Ruoli basati sui gruppi — Mappa automaticamente i gruppi IdP ai ruoli EmDash
Configurazione
- Crea un’applicazione Cloudflare Access per il tuo sito EmDash
- Prendi nota dell’Application Audience (AUD) Tag dalle impostazioni dell’applicazione
- Configura EmDash per utilizzare 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
}),
}),
],
});
Opzioni di configurazione
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
teamDomain | string | richiesto | Il tuo dominio team Access (ad esempio, myteam.cloudflareaccess.com) |
audience | string | richiesto | Tag Application Audience (AUD) dalle impostazioni Access |
autoProvision | boolean | true | Creare utenti EmDash al primo accesso Access |
defaultRole | number | 30 | Ruolo per utenti che non corrispondono a nessun gruppo (30 = Author) |
syncRoles | boolean | false | Aggiornare ruolo ad ogni accesso in base ai gruppi IdP |
roleMapping | object | — | Mappare nomi di gruppi IdP a livelli di ruoli |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | Nome variabile d’ambiente per il tag audience (alternativa alla codifica fissa) |
Mappatura dei ruoli
Mappa i tuoi gruppi IdP ai ruoli EmDash:
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "abc123...",
roleMapping: {
Admins: 50, // Admin
"Content Editors": 40, // Editor
Writers: 30, // Author
},
defaultRole: 20, // Contributor per utenti che non sono in nessun gruppo
}),
});
Il primo gruppo corrispondente vince se un utente appartiene a più gruppi. Il primo utente ad accedere al sito diventa sempre Admin, indipendentemente dai gruppi.
Comportamento di sincronizzazione dei ruoli
Per impostazione predefinita (syncRoles: false), il ruolo di un utente viene impostato quando accede per la prima volta e non cambia successivamente. Questo consente agli amministratori di regolare manualmente i ruoli in EmDash.
Imposta syncRoles: true se vuoi che i gruppi IdP siano autorevoli — il ruolo dell’utente verrà aggiornato ad ogni accesso in base ai suoi gruppi attuali.
Come funziona
- L’utente visita
/_emdash/admin - Cloudflare Access intercetta e reindirizza al tuo IdP
- L’utente si autentica (SSO, MFA, ecc.)
- Access imposta un JWT firmato nella richiesta
- EmDash valida il JWT e crea/autentica l’utente
Funzionalità disabilitate
Quando Access è abilitato, queste funzionalità non sono disponibili:
- Pagina di accesso (
/_emdash/admin/login) - Registrazione e gestione delle passkey
- Accesso OAuth
- Accesso tramite link magico
- Auto-registrazione
- Inviti utente
La gestione degli utenti viene effettuata interamente tramite le tue politiche Cloudflare Access.
Risoluzione dei problemi
”Nessun JWT Access presente”
La richiesta ha raggiunto EmDash senza JWT Access. Questo significa:
- Access non è configurato per proteggere la tua applicazione
- La politica Access non corrisponde alle route dell’amministrazione
Verifica che la tua applicazione Access copra /_emdash/admin/*.
”Mancata corrispondenza dell’audience JWT”
L’audience nella tua configurazione non corrisponde al JWT. Ricontrolla il Tag Application Audience nelle impostazioni della tua applicazione Access.
”Utente non autorizzato”
L’utente si è autenticato tramite Access ma autoProvision è false e non esiste in EmDash. O:
- Imposta
autoProvision: true, oppure - Crea l’utente manualmente prima che acceda