Salta ai contenuti

Autenticazione e gestione utenti

Prima di implementare l’autenticazione personalizzata, raccomandiamo vivamente di considerare FireCMS Pro o FireCMS Cloud, che includono:

  • ✅ Sistema di gestione utenti integrato
  • ✅ Permessi basati su ruoli (Admin, Editor, Viewer)
  • ✅ Interfaccia di gestione team
  • ✅ Sistema di invito utenti
  • ✅ Permessi granulari a livello di collezione e campo
  • ✅ Log di audit e tracciamento attività utente
  • ✅ Funzionalità di sicurezza di livello enterprise

Queste soluzioni forniscono un sistema completo di autenticazione e autorizzazione out-of-the-box, risparmiando tempo di sviluppo significativo e garantendo le best practice di sicurezza.

Scopri di più sulla Gestione Utenti in FireCMS Pro →

Prova FireCMS Cloud →

Questa sezione spiega come creare una collezione users per gestire gli utenti.

Questa collezione memorizzerà i tuoi utenti.

import { buildCollection, buildProperty } from "@firecms/core";
export type User = {
name: string;
email: string;
};
export const usersCollection = buildCollection<User>({
name: "Users",
singularName: "User",
path: "users",
properties: {
name: buildProperty({
name: "Name",
validation: { required: true },
dataType: "string"
}),
email: buildProperty({
name: "Email",
validation: { required: true, email: true },
dataType: "string"
})
}
});

Ora aggiungiamod un role ai nostri utenti e usiamolo per controllare l’accesso.

Passaggio 1: Aggiorna la collezione “Users” con i ruoli

Sezione intitolata “Passaggio 1: Aggiorna la collezione “Users” con i ruoli”

Aggiungi una proprietà role al tuo tipo User e alla collezione.

import { buildCollection, buildProperty } from "@firecms/core";
export enum UserRole {
admin = "admin",
editor = "editor",
viewer = "viewer",
}
export type User = {
name: string;
email: string;
role: UserRole;
}
export const usersCollection = buildCollection<User>({
name: "Users",
singularName: "User",
path: "users",
properties: {
name: buildProperty({
name: "Name",
validation: { required: true },
dataType: "string"
}),
email: buildProperty({
name: "Email",
validation: { required: true, email: true },
dataType: "string"
}),
role: buildProperty({
name: "Role",
validation: { required: true },
dataType: "string",
enumValues: {
admin: "Admin",
editor: "Editor",
viewer: "Viewer"
}
})
}
});

Passaggio 2: Implementa un autenticatore basato su ruoli

Sezione intitolata “Passaggio 2: Implementa un autenticatore basato su ruoli”

Prima, crea un nuovo file chiamato src/custom_authenticator.ts.

src/custom_authenticator.ts

import { Authenticator } from "@firecms/core";
import { FirebaseUserWrapper } from "@firecms/firebase";
import { User } from "./collections/users";
export const roleBasedAuthenticator: Authenticator<FirebaseUserWrapper> = async ({
user,
authController,
dataSourceDelegate
}) => {
if (!user?.email) return false;
try {
const userEntities = await dataSourceDelegate.fetchCollection<User>({
path: "users",
filter: { email: ["==", user.email] }
});
if (userEntities && userEntities.length > 0) {
const member = userEntities[0].values;
authController.setExtra({
role: member.role
});
return true;
}
return false;
} catch (error) {
console.error("Authentication error:", error);
return false;
}
};

Usa la callback permissions nelle tue collezioni per controllare l’accesso in base al ruolo dell’utente.

import { buildCollection } from "@firecms/core";
import { UserRole } from "./collections/users";
export const postsCollection = buildCollection({
name: "Posts",
path: "posts",
permissions: ({ authController }) => {
const userRole = authController.extra?.role;
return {
read: true, // Tutti i ruoli possono leggere
edit: userRole === UserRole.admin || userRole === UserRole.editor,
create: userRole === UserRole.admin || userRole === UserRole.editor,
delete: userRole === UserRole.admin
};
},
// ... proprietà
});

Parte 3: Uso dei Custom Claims Firebase per i permessi

Sezione intitolata “Parte 3: Uso dei Custom Claims Firebase per i permessi”

Un’alternativa alla memorizzazione dei ruoli in Firestore è usare i custom claims di Firebase Authentication.

Devi impostare i custom claims per un utente da un ambiente backend usando l’SDK Firebase Admin. Questo viene tipicamente fatto in una Cloud Function.

// Esempio Cloud Function per impostare un claim ruolo
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();
export const setUserRole = functions.https.onCall(async (data, context) => {
if (!context.auth?.token.admin) {
throw new functions.https.HttpsError("permission-denied", "Must be an admin to set roles.");
}
const { uid, role } = data;
await admin.auth().setCustomUserClaims(uid, { role });
return { message: `Success! User ${uid} has been given the role of ${role}.` };
});

Passaggio 2: Implementa un autenticatore basato su claims

Sezione intitolata “Passaggio 2: Implementa un autenticatore basato su claims”
import { Authenticator } from "@firecms/core";
import { FirebaseUserWrapper } from "@firecms/firebase";
export const claimsAuthenticator: Authenticator<FirebaseUserWrapper> = async ({
user,
authController
}) => {
if (!user) return false;
try {
const idTokenResult = await user.firebaseUser.getIdTokenResult(true);
const role = idTokenResult.claims.role || "viewer";
authController.setExtra({ role });
return true;
} catch (error) {
console.error("Authentication error:", error);
return false;
}
};
  • Regole di sicurezza Firestore: Applica sempre le regole di sicurezza nel tuo backend. I permessi lato client sono per scopi UI/UX e possono essere aggirati.
  • Validazione lato server: Per le operazioni critiche, valida i permessi su un server.
  • Principio del minimo privilegio: Concedi agli utenti il livello minimo di accesso di cui hanno bisogno.