Migration depuis Firebase Auth
Firebase Authentication est un choix populaire pour démarrer rapidement, mais à mesure que les applications grandissent, les équipes ont souvent besoin de fonctionnalités enterprise que Firebase n’offre pas : SSO enterprise (SAML/OIDC), provisioning SCIM, autorisation fine-grained, organisations avec multi-tenancy B2B, certifications de conformité et options de déploiement self-hosted. Auris fournit tout cela en maintenant la developer experience de Firebase Auth.
Ce guide illustre comment exporter les utilisateurs de Firebase, gérer la transition des hashes de mots de passe, remplacer le SDK Firebase par le SDK Auris et migrer les custom claims et security rules.
Mapping des Fonctionnalités
| Fonctionnalité Firebase Auth | Équivalent Auris | Notes |
|---|---|---|
| Email/Password Login | Hosted Login Pages | Flux OAuth2 PKCE, UI branded par tenant |
| Social Provider (Google, Facebook, etc.) | Social Login | 9 fournisseurs, même flux OAuth2 |
| Phone Auth (SMS) | SMS OTP | Fournisseur Twilio, 2FA et passwordless |
| Anonymous Auth | Non disponible | Utilise magic link pour l’onboarding à faible friction |
| Custom Claims | Custom JWT Claims | Par application, 5 types de valeur, configurable par admin |
| Firebase Admin SDK | Management Client (@auris/js) | Client credentials M2M, CRUD utilisateurs/rôles/org |
| Security Rules | FGA (Fine-Grained Authorization) + RBAC | ReBAC style Zanzibar, plus puissant que les Security Rules |
| Email Link Sign-In | Magic Links | Basé sur token, support auto-signup |
| Multi-Factor Auth | Multi-Factor Auth | TOTP, SMS, WebAuthn (Firebase supporte seulement SMS + TOTP) |
| Firebase UI | Hosted Login Pages | Complètement géré, branding personnalisable |
| User Management (Console) | Console Auris | Console admin complète avec rôles, permissions, sessions |
| ID Token Verification | Vérification JWT (JWKS) | RS256 avec endpoint JWKS, vérificateur @auris/js |
| Blocking Functions | Actions Engine | 6 points de déclenchement, JS sandboxed, éditeur visuel |
Fonctionnalités qu’Auris Ajoute au-delà de Firebase
| Fonctionnalité | Description |
|---|---|
| Enterprise SSO | Fédération SAML 2.0 + OIDC pour les IdP d’entreprise |
| SCIM 2.0 Provisioning | Sync automatisé des utilisateurs avec Okta, Azure AD, etc. |
| Organizations B2B | Multi-org avec rôles membres et invitations |
| Fine-Grained Authorization (FGA) | Contrôle d’accès relationship-based style Zanzibar |
| Roles & Permissions | RBAC tri-state avec scoping par application |
| Custom Domains | Pages auth white-label sous ton domaine |
| Log Streaming | Exporte les logs d’audit sur Datadog, Splunk, S3 |
| Webhooks | Notifications d’événements en temps réel signées HMAC |
| Rate Limiting | Limitation de débit par niveaux avec headers standard |
| Attack Protection | Règles IP, blocage brute-force, CAPTCHA, détection connexions suspectes |
Étapes de Migration
Étape 1 : Exporter les Utilisateurs depuis Firebase
Utilise le Firebase Admin SDK pour exporter tous les utilisateurs :
// export-firebase-users.ts
import admin from 'firebase-admin'
import fs from 'fs'
admin.initializeApp({
credential: admin.credential.cert('./service-account-key.json'),
})
async function exportAllUsers() {
const users = []
let nextPageToken
do {
const result = await admin.auth().listUsers(1000, nextPageToken)
for (const user of result.users) {
users.push({
uid: user.uid,
email: user.email || '',
emailVerified: user.emailVerified,
displayName: user.displayName || '',
phoneNumber: user.phoneNumber,
disabled: user.disabled,
customClaims: user.customClaims,
passwordHash: user.passwordHash,
passwordSalt: user.passwordSalt,
providerData: user.providerData.map((p) => ({
providerId: p.providerId,
uid: p.uid,
})),
createdAt: user.metadata.creationTime,
})
}
nextPageToken = result.pageToken
console.log(`${users.length} utilisateurs exportés...`)
} while (nextPageToken)
return users
}
exportAllUsers().then((users) => {
fs.writeFileSync('firebase-users-export.json', JSON.stringify(users, null, 2))
console.log(`Total : ${users.length} utilisateurs exportés`)
})Firebase exporte les hashes de mots de passe en utilisant un algorithme scrypt modifié (Firebase scrypt). Ces hashes ne peuvent pas être vérifiés directement par Auris car Auris utilise bcrypt. Tu devras gérer la migration des mots de passe en utilisant le pattern de migration lazy décrit ci-dessous.
Étape 2 : Gérer la Migration des Hashes de Mots de Passe
Firebase utilise une variante scrypt personnalisée pour le hashing des mots de passe qui n’est pas compatible avec bcrypt utilisé par Auris. Il y a deux approches :
Option A : Migration Lazy (Recommandée)
Le pattern de migration lazy rehash les mots de passe de façon transparente au fur et à mesure que les utilisateurs se connectent. Cela fournit zéro friction pour les utilisateurs finaux.
Comment ça fonctionne :
- Importe les utilisateurs dans Auris sans mot de passe (ils seront créés comme comptes sans mot de passe)
- Quand un utilisateur tente de se connecter sur Auris et n’a pas de mot de passe défini, Auris retourne un flux spécifique
- Ton application tente de vérifier la credential sur Firebase en utilisant l’Admin SDK
- Si la vérification Firebase réussit, définis le mot de passe de l’utilisateur dans Auris via l’Admin API
- Toutes les connexions suivantes passent directement par Auris
// Middleware pour la migration lazy des mots de passe
async function lazyMigratePassword(
email: string,
password: string,
aurisManagementToken: string
): Promise<boolean> {
try {
// Étape 1 : Essayer de se connecter avec Firebase
const firebaseResponse = await fetch(
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${process.env.FIREBASE_API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password, returnSecureToken: false }),
}
)
if (!firebaseResponse.ok) {
return false // Credentials invalides aussi dans Firebase
}
// Étape 2 : Firebase a vérifié le mot de passe — le définir dans Auris
const userResponse = await fetch(
`https://auth.votreentreprise.com/api/users?email=${encodeURIComponent(email)}`,
{
headers: {
Authorization: `Bearer ${aurisManagementToken}`,
'x-tenant': 'votre-tenant-id',
},
}
)
const userData = await userResponse.json()
const userId = userData.data?.[0]?.id
if (!userId) return false
// Étape 3 : Définir le mot de passe dans Auris
await fetch(
`https://auth.votreentreprise.com/api/users/${userId}/set-password`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${aurisManagementToken}`,
'x-tenant': 'votre-tenant-id',
'Content-Type': 'application/json',
},
body: JSON.stringify({ password }),
}
)
console.log(`Mot de passe migré pour l'utilisateur : ${email}`)
return true
} catch (error) {
console.error(`Migration du mot de passe échouée pour ${email} :`, error)
return false
}
}Option B : Forcer la Réinitialisation du Mot de Passe (Plus Simple)
- Importe les utilisateurs sans mot de passe
- Après l’import, déclenche des e-mails de réinitialisation de mot de passe pour tous les utilisateurs
- Les utilisateurs définissent un nouveau mot de passe à la première connexion
Étape 3 : Importer les Utilisateurs dans Auris
Transforme l’export Firebase au format d’import Auris :
// transform-firebase-users.ts
import fs from 'fs'
const firebaseUsers = JSON.parse(
fs.readFileSync('firebase-users-export.json', 'utf-8')
)
const aurisUsers = firebaseUsers
.filter((u) => u.email && !u.disabled)
.map((user) => {
const nameParts = (user.displayName || '').split(' ')
return {
email: user.email,
firstName: nameParts[0] || '',
lastName: nameParts.slice(1).join(' ') || '',
emailVerified: user.emailVerified,
}
})
fs.writeFileSync('auris-import.json', JSON.stringify(aurisUsers, null, 2))
console.log(`${aurisUsers.length} utilisateurs transformés pour l'import`)Importe dans Auris :
curl -X POST https://auth.votreentreprise.com/api/users/import \
-H "Authorization: Bearer $AURIS_ACCESS_TOKEN" \
-H "x-tenant: votre-tenant-id" \
-F "[email protected]" \
-F "format=json"Étape 4 : Créer une Application dans la Console Auris
- Ouvre la Console Auris et va sur Applications puis Créer une Application
- Sélectionne WEB comme type d’application
- Saisis le nom de l’application
- Ajoute tes Callback URLs
- Ajoute tes Origines Autorisées
- Enregistre et note le Client ID
Étape 5 : Remplacer le SDK Firebase par le SDK Auris
# Supprimer Firebase
npm uninstall firebase firebase-admin
# Installer Auris
npm install @auris/js @auris/react
# Pour Next.js :
npm install @auris/nextjsÉtape 6 : Mettre à Jour le Code de l’Application
Initialisation :
// AVANT (Firebase)
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
const app = initializeApp({ apiKey: 'AIza...', authDomain: 'myapp.firebaseapp.com' })
const auth = getAuth(app)
// APRÈS (Auris)
import { AurisClient } from '@auris/js'
const auris = new AurisClient({
domain: 'auth.votreentreprise.com',
clientId: 'votre-client-id',
redirectUri: 'http://localhost:3000/callback',
autoRefresh: true,
})Authentification (React) :
// AVANT (Firebase)
import { useAuthState } from 'react-firebase-hooks/auth'
const [user, loading] = useAuthState(auth)
// APRÈS (Auris)
import { useAuris } from '@auris/react'
const { user, isLoading, isAuthenticated, loginWithRedirect, logout } = useAuris()Obtenir le Token pour les Appels API :
// AVANT (Firebase)
const token = await auth.currentUser?.getIdToken()
// APRÈS (Auris)
const token = await auris.getAccessToken()
// Le reste du code reste inchangé
const response = await fetch('/api/protected', {
headers: { Authorization: `Bearer ${token}` },
})Vérification de Token côté Serveur :
// AVANT (Firebase Admin SDK)
import admin from 'firebase-admin'
async function verifyToken(token: string) {
const decoded = await admin.auth().verifyIdToken(token)
return decoded
}
// APRÈS (Auris — en utilisant JWKS)
import { verifyJwt } from '@auris/js/jwt-verify'
async function verifyToken(token: string) {
const decoded = await verifyJwt(token, {
jwksUrl: 'https://auth.votreentreprise.com/.well-known/jwks.json',
})
return decoded
}
// Ou en utilisant le helper Next.js :
import { getSession } from '@auris/nextjs/server'
export async function GET(req: Request) {
const session = await getSession()
if (!session) {
return Response.json({ error: 'Non autorisé' }, { status: 401 })
}
return Response.json({ userId: session.user.id })
}Social Login (Google) :
// AVANT (Firebase)
import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth'
const provider = new GoogleAuthProvider()
const result = await signInWithPopup(auth, provider)
// APRÈS (Auris)
// Le social login est géré par la Hosted Login page — aucune modification de code.
// Configure Google comme fournisseur social dans Console → Authentification → Social Login.
// Les utilisateurs voient automatiquement le bouton Google sur la page de connexion hébergée.
// Pour aller directement à Google :
await auris.loginWithRedirect({ connection: 'google' })Étape 7 : Migrer les Custom Claims
Les custom claims Firebase sont typiquement définis via l’Admin SDK :
// AVANT (Firebase)
await admin.auth().setCustomUserClaims(uid, {
role: 'admin',
plan: 'enterprise',
orgId: 'org_123',
})Dans Auris, les custom claims sont configurés par application dans la Console :
- Va sur Applications puis sélectionne ton app puis onglet Custom Claims
- Ajoute les claims :
roleavec type Attribut Utilisateur mappé àroles[0].nameplanavec type Statique valeurenterpriseorgIdavec type Attribut Utilisateur mappé àmetadata.orgId
Consulte le guide Custom JWT Claims pour la référence complète.
Étape 8 : Migrer les Security Rules vers FGA
Les Firebase Security Rules sont des règles de contrôle d’accès déclaratives liées aux chemins Firestore ou Realtime Database. Auris utilise la Fine-Grained Authorization (FGA) basée sur le modèle Zanzibar, qui est plus puissante et découplée du layer de données.
Exemple de Firebase Security Rules :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /documents/{docId} {
allow read: if request.auth != null &&
(resource.data.ownerId == request.auth.uid ||
request.auth.uid in resource.data.viewers);
allow write: if request.auth != null &&
resource.data.ownerId == request.auth.uid;
}
}
}Modèle FGA Auris équivalent :
model
schema 1.1
type user
type document
relations
define owner: [user]
define viewer: [user] or owner
define editor: [user] or owner
define can_read: viewer
define can_write: editorÉcris des tuples de relation pour représenter les données :
# Accorder la propriété
curl -X POST https://auth.votredomaine.com/api/fga/tuples \
-H "Authorization: Bearer $AURIS_ACCESS_TOKEN" \
-H "x-tenant: votre-tenant-id" \
-H "Content-Type: application/json" \
-d '{
"objectType": "document",
"objectId": "doc_123",
"relation": "owner",
"subjectType": "user",
"subjectId": "usr_abc"
}'Vérifie l’accès dans ton application :
import { AurisClient } from '@auris/js'
const result = await auris.fga.check({
objectType: 'document',
objectId: 'doc_123',
relation: 'can_read',
subjectType: 'user',
subjectId: 'usr_abc',
})
if (result.allowed) {
// L'utilisateur peut lire le document
}Consulte le guide Autorisation Fine-Grained pour la référence FGA complète.
Timeline de Migration
Une migration typique de Firebase vers Auris suit cette timeline :
| Semaine | Activités |
|---|---|
| 1 | Configurer le tenant Auris, créer des applications, configurer les fournisseurs sociaux, exporter les utilisateurs Firebase |
| 2 | Importer les utilisateurs dans Auris, implémenter l’endpoint de migration lazy des mots de passe, configurer le modèle FGA |
| 3 | Remplacer le SDK Firebase par le SDK Auris dans l’application, tester tous les flux auth |
| 4 | Déploiement en staging et QA, migrer les custom claims, configurer les webhooks/log streaming |
| 5 | Déploiement en production, surveiller la progression de la migration lazy, commencer la désactivation de Firebase |
| 6-8 | Surveiller le taux de complétion de la migration, envoyer des réinitialisations de mots de passe aux utilisateurs non migrés |
| 8+ | Désactiver le projet Firebase |
Checklist Post-Migration
- Tous les utilisateurs peuvent se connecter (email/mot de passe, social, téléphone)
- La migration lazy des mots de passe fonctionne (vérifie les logs d’audit Auris)
- Les custom claims apparaissent dans les access tokens
- Les vérifications d’autorisation FGA retournent des résultats corrects
- La vérification de token côté serveur utilise le JWKS Auris
- Les fournisseurs de connexion sociale (Google, Facebook, etc.) sont configurés
- Les événements webhook sont livrés
- Le SDK Firebase est complètement supprimé du codebase
- Les références à l’émulateur Firebase Auth sont supprimées des tests
- La facturation du projet Firebase est réduite ou annulée
Maintiens le projet Firebase actif pendant la période de migration lazy. Surveille le pourcentage d’utilisateurs qui ont migré leurs mots de passe en vérifiant les logs d’audit Auris pour les événements user.password_changed. Une fois que la migration atteint 95%+ des utilisateurs actifs, envoie un e-mail de réinitialisation de mot de passe aux utilisateurs restants et planifie la désactivation de Firebase.
Guides Associés
- Connexion Hébergée (PKCE) — Implémenter le flux de connexion
- Custom JWT Claims — Remplacer les custom claims Firebase
- Autorisation Fine-Grained — Remplacer les Firebase Security Rules
- Social Login — Configurer les fournisseurs OAuth2
- Import/Export Utilisateurs — Migration d’utilisateurs en masse
- Migration depuis Auth0 — Guide de migration alternatif