Verifica delle email con Firebase
Firebase Authentication permette di intercettare gli eventi di registrazione con funzioni bloccanti beforeCreate. Questo tutorial aggiunge la verifica di Mailbeam a quell'hook, così le email non valide e usa e getta vengono bloccate prima che il record dell'utente venga creato in Firebase.
Prerequisiti
- Un progetto Firebase con piano Blaze (necessario per le Cloud Functions)
- La CLI di Firebase installata
- Una chiave API di Mailbeam (iscriviti gratis)
Preparazione
firebase init functions
cd functions
npm install axiosDefinisci la chiave di Mailbeam come variabile d'ambiente di Firebase:
firebase functions:config:set mailbeam.key="mb_live_xxxxxxxxxxxxxxxxxxxx"Crea la funzione bloccante
// functions/index.js
const functions = require("firebase-functions");
const { getAuth } = require("firebase-admin/auth");
const axios = require("axios");
// beforeCreate viene eseguita PRIMA che l'utente venga scritto in Firebase Auth
exports.validateEmailBeforeCreate = functions.auth
.user()
.beforeCreate(async (user, context) => {
const email = user.email;
if (!email) return; // Senza email: altri provider, salta
const apiKey = functions.config().mailbeam.key;
try {
const { data } = await axios.post(
"https://api.mailbeam.dev/v1/verify",
{ email },
{
headers: { Authorization: `Bearer ${apiKey}` },
timeout: 5000,
}
);
const { valid, score, reason } = data;
if (!valid || score < 60) {
const message =
reason === "disposable_domain"
? "Usa un indirizzo email permanente, non uno temporaneo."
: "Inserisci un indirizzo email valido e raggiungibile.";
throw new functions.auth.HttpsError("invalid-argument", message);
}
} catch (err) {
// Se è già il nostro HttpsError, rilancialo
if (err.code === "functions/invalid-argument") throw err;
// Altrimenti: registra l'errore e lascia passare
functions.logger.error("Verifica di Mailbeam fallita", { error: err.message });
}
});Versione in TypeScript
// functions/src/index.ts
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import axios from "axios";
admin.initializeApp();
export const validateEmailBeforeCreate = functions.auth
.user()
.beforeCreate(async (user) => {
if (!user.email) return;
const apiKey = functions.config().mailbeam.key;
try {
const { data } = await axios.post<{
valid: boolean;
score: number;
reason: string | null;
}>(
"https://api.mailbeam.dev/v1/verify",
{ email: user.email },
{ headers: { Authorization: `Bearer ${apiKey}` }, timeout: 5000 }
);
if (!data.valid || data.score < 60) {
throw new functions.auth.HttpsError(
"invalid-argument",
data.reason === "disposable_domain"
? "Usa un indirizzo email permanente."
: "Usa un indirizzo email valido e raggiungibile."
);
}
} catch (err: unknown) {
if ((err as { code?: string }).code === "functions/invalid-argument") throw err;
functions.logger.error("Errore di Mailbeam", err);
}
});Pubblicazione
firebase deploy --only functionsProve
// Usa la Emulator Suite di Firebase per provare in locale
firebase emulators:start
// Prova a creare un utente con un'email usa e getta dall'SDK di Firebase
const { createUserWithEmailAndPassword } = require("firebase/auth");
try {
await createUserWithEmailAndPassword(auth, "temp@mailinator.com", "password");
} catch (error) {
console.log(error.code); // "auth/invalid-argument"
console.log(error.message); // "Usa un indirizzo email permanente."
}Buone pratiche
- Usa
beforeCreate, nononCreate:beforeCreategira prima che il record venga salvato,onCreatedopo - Rilancia sempre
functions.auth.HttpsErrore lascia passare davanti a qualsiasi altro errore - Usa
functions.logger.error, nonconsole.error, per avere registri strutturati in Firebase