Vérification d'e-mails avec Firebase
Firebase Authentication permet d'intercepter les inscriptions via les fonctions bloquantes beforeCreate. Ce tutoriel ajoute la vérification Mailbeam à ce hook, de sorte que les adresses invalides et jetables sont bloquées avant qu'un enregistrement utilisateur Firebase ne soit créé.
Prérequis
- Un projet Firebase sur le plan Blaze (nécessaire pour les Cloud Functions)
- La CLI Firebase installée
- Une clé d'API Mailbeam (inscription gratuite)
Mise en place
firebase init functions
cd functions
npm install axiosDéclarez la clé Mailbeam comme variable d'environnement Firebase :
firebase functions:config:set mailbeam.key="mb_live_xxxxxxxxxxxxxxxxxxxx"Créer la fonction bloquante
// functions/index.js
const functions = require("firebase-functions");
const { getAuth } = require("firebase-admin/auth");
const axios = require("axios");
// beforeCreate s'exécute AVANT l'écriture de l'utilisateur dans Firebase Auth
exports.validateEmailBeforeCreate = functions.auth
.user()
.beforeCreate(async (user, context) => {
const email = user.email;
if (!email) return; // Pas d'adresse — autres fournisseurs, on passe
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"
? "Merci d'utiliser une adresse e-mail permanente, pas une adresse temporaire."
: "Merci de fournir une adresse e-mail valide et joignable.";
throw new functions.auth.HttpsError("invalid-argument", message);
}
} catch (err) {
// S'il s'agit déjà de notre HttpsError, on la relance
if (err.code === "functions/invalid-argument") throw err;
// Sinon : on journalise et on laisse passer
functions.logger.error("Échec de la vérification Mailbeam", { error: err.message });
}
});Version 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"
? "Merci d'utiliser une adresse e-mail permanente."
: "Merci d'utiliser une adresse e-mail valide et joignable."
);
}
} catch (err: unknown) {
if ((err as { code?: string }).code === "functions/invalid-argument") throw err;
functions.logger.error("Erreur Mailbeam", err);
}
});Déployer
firebase deploy --only functionsTester
// Utilisez la Firebase Emulator Suite pour tester en local
firebase emulators:start
// Essayez de créer un utilisateur avec une adresse jetable via le SDK 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); // "Merci d'utiliser une adresse e-mail permanente."
}Bonnes pratiques
- Utilisez
beforeCreateet nononCreate:beforeCreates'exécute avant l'enregistrement,onCreateaprès - Relancez toujours
functions.auth.HttpsErroret échouez en mode permissif pour toutes les autres erreurs - Utilisez
functions.logger.errorplutôt queconsole.error, pour une journalisation structurée dans Firebase