Authentification PocketBase 2026 : Email, OAuth2, OTP et MFA – Guide complet
L'authentification est au cœur de toute application web ou mobile sécurisée. Dans PocketBase, un backend open-source léger, elle est intégrée nativement et gérée de manière stateless, ce qui signifie que les tokens d'authentification sont vérifiés sans sessions serveur persistantes. Cela simplifie le développement pour les startups et PME qui cherchent une solution rapide à déployer, sans gérer une base de données complexe pour les sessions.
Ce guide s'adresse aux débutants : développeurs juniors, fondateurs de startups ou responsables techniques en PME qui veulent implémenter une authentification robuste sans réinventer la roue. Nous couvrons les méthodes principales – email/mot de passe, OAuth2, OTP – ainsi que la collection des utilisateurs, les refresh tokens, le multi-facteurs (MFA) et la gestion côté client. Tout est basé sur la documentation officielle de PocketBase (version actuelle en novembre 2025), avec des exemples concrets en JavaScript et Dart pour les SDK client. À la fin, vous saurez configurer et utiliser ces fonctionnalités pour votre projet.
PocketBase utilise des tokens JWT (JSON Web Tokens) signés avec l'algorithme HS256. Chaque requête authentifiée inclut un header Authorization: Bearer VOTRE_TOKEN. Pas de logout centralisé : le client efface simplement son token local. Commençons par les bases.
1. La collection _users : Le fondement de l'authentification
Dans PocketBase, l'authentification repose sur une collection spéciale de type "Auth". Par défaut, elle s'appelle _users, mais vous pouvez la renommer (par exemple, en "utilisateurs" pour un projet francophone). Cette collection stocke les profils utilisateurs avec des champs obligatoires pour l'auth : email (identifiant par défaut), password (haché), verified (booléen pour la confirmation email) et last_reset_sent_at (timestamp pour les resets).
Créer et configurer la collection _users
- Via l'interface admin : Lancez PocketBase (
./pocketbase serve) et accédez àhttp://127.0.0.1:8090/_/. Cliquez sur "Collections" > "New collection" > Sélectionnez "Auth" . Nommez-la_users. Ajoutez des champs optionnels commenom(text),role(select avec options "admin", "user"). - Champs obligatoires : L'identité (par défaut
email) doit être unique avec un index UNIQUE. Changez-la enusernamesi préféré, via les options de la collection. - Options d'auth : Dans l'onglet "Auth" de la collection :
- Activez "Confirm email changes" pour valider les modifications d'email.
- Définissez "Max active periods" (défaut : 0, illimité) pour limiter les sessions actives par utilisateur.
- Configurez les templates email pour les notifications (OTP, reset, etc.).
Exemple de configuration basique : Une collection _users avec champs email (email, required, unique), password (auto-généré pour hash), nom (text) et avatar (file pour upload).
Cette collection génère automatiquement une API REST pour les opérations d'auth. Les superutilisateurs (collection _superusers) ont un accès total et bypassent les règles, mais sans support OAuth2.
Pour les PME, cette setup est idéale : scalable avec SQLite embarqué, et extensible via hooks pour ajouter de la logique métier (ex. : envoi de bienvenue post-inscription).
2. Authentification par email et mot de passe
La méthode la plus simple et courante : email + mot de passe. Elle nécessite d'activer l'option "Identity/Password" dans les settings de la collection _users.
Étapes d'implémentation
- Inscription : Utilisez l'endpoint POST
/api/collections/_users/recordsavec body{ "email": "[email protected]", "password": "motdepasse123", "passwordConfirm": "motdepasse123" }. PocketBase hache le mot de passe et crée l'enregistrement. - Connexion : Appelez l'API
authWithPassword(identity, password). Sur succès, vous recevez un token JWT et le record utilisateur, stockés localement dans l'SDK. - Vérification : Le token expire (défaut : 1 heure, configurable globalement). Vérifiez avec
isValidsur l'authStore.
Exemple en JavaScript (SDK client)
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
// Connexion
try {
const authData = await pb.collection('_users').authWithPassword('[email protected]', 'motdepasse123');
console.log('Connecté ! Token:', pb.authStore.token);
console.log('Utilisateur ID:', pb.authStore.record.id);
} catch (error) {
console.error('Erreur de connexion:', error);
}
// Déconnexion (efface le token local)
pb.authStore.clear();
Exemple en Dart (pour Flutter/mobile)
import 'package:pocketbase/pocketbase.dart';
final pb = PocketBase('http://127.0.0.1:8090');
// Connexion
try {
final authData = await pb.collection('_users').authWithPassword('[email protected]', 'motdepasse123');
print('Connecté ! Token: ${pb.authStore.token}');
print('Utilisateur ID: ${pb.authStore.record.id}');
} on ClientException catch (e) {
print('Erreur: ${e.message}');
}
// Déconnexion
pb.authStore.clear();
Pour les startups, activez la confirmation email pour éviter les faux comptes. Ajoutez une règle d'accès comme @request.auth.id != "" pour restreindre les lectures aux utilisateurs connectés.
Cette méthode est sécurisée par défaut : hash bcrypt pour les mots de passe, et tokens signés. Limitez les tentatives de login via hooks pour contrer les brute-force.
3. Authentification OAuth2 : Intégrez Google, GitHub et plus
OAuth2 permet une connexion via des providers tiers comme Google, GitHub, Microsoft ou Apple. Pas besoin de gérer les mots de passe : l'utilisateur s'authentifie chez le provider, qui renvoie un token à PocketBase.
Configuration du provider
- Créez une app chez le provider :
- Google : Console Google Cloud > Credentials > OAuth 2.0 Client ID. Redirect URI :
https://votre-domaine.com/api/collections/_users/auth-with-oauth2/callback(ou local :http://127.0.0.1:8090/...). - Obtenez Client ID et Secret.
- Google : Console Google Cloud > Credentials > OAuth 2.0 Client ID. Redirect URI :
- Dans PocketBase : Onglet "OAuth2" de la collection
_users> Ajoutez le provider > Saisissez ID/Secret. Activez-le. - Champs mappés : Associez les infos du provider (ex. :
namedu Google user versnomdans_users).
Méthodes d'auth
PocketBase supporte deux flux : "All-in-One" (recommandé, avec popup) et "Manual Code Exchange".
Flux All-in-One (popup automatique)
L'SDK gère le popup et la realtime subscription pour fermer automatiquement.
JavaScript :
const pb = new PocketBase('http://127.0.0.1:8090');
pb.collection('_users').authWithOAuth2({ provider: 'google' }, (error) => {
if (error) {
console.error('OAuth erreur:', error);
return;
}
console.log('Connecté via Google:', pb.authStore.record);
// Déconnexion : pb.authStore.clear();
});
Dart (Flutter) :
final pb = PocketBase('http://127.0.0.1:8090');
try {
final authData = await pb.collection('_users').authWithOAuth2('google', (url) async {
// Ouvrez l'URL dans un webview ou navigateur
await launchUrl(Uri.parse(url.toString()));
});
print('Connecté via Google: ${pb.authStore.record}');
} catch (e) {
print('Erreur OAuth: $e');
}
Flux Manual (pour contrôle fin)
- Générez un lien auth via
listAuthMethods()pour obtenir l'URL du provider. - Redirigez l'utilisateur, capturez le code callback.
- Échangez via
authWithOAuth2Code(provider, code, codeVerifier, redirectUrl).
Exemple HTML/JS pour une page de liens OAuth (servie statiquement) :
- Liste les providers et génère des liens sécurisés avec state et codeVerifier (PKCE pour sécurité).
Pour Apple Sign-In : Utilisez response_mode=form_post pour obtenir nom/email complets.
Pour les PME, OAuth2 réduit le churn : les utilisateurs préfèrent "Se connecter avec Google". Testez en local, puis déployez avec HTTPS obligatoire pour les redirects.
4. Authentification par OTP : Simple et sans mot de passe
L'OTP (One-Time Password) envoie un code à 6 chiffres par email pour une connexion sécurisée, sans mot de passe permanent. Activez l'option "One-time password (OTP)" dans les settings de _users.
Flux complet
- Demande d'OTP :
requestOTP(email)renvoie unotpId(même si l'email n'existe pas, pour éviter l'énumération). - Envoi email : PocketBase utilise son mailer intégré (SMTP configurable dans settings). Personnalisez le template avec
{OTP}et{OTP_ID}(ex. : lien cliquablevotre-app.com/verify?otpId={OTP_ID}&otp={OTP}). - Validation :
authWithOTP(otpId, code). Sur succès, l'email est marqué comme vérifié, et un token est généré.
Exemple JavaScript
const pb = new PocketBase('http://127.0.0.1:8090');
// Demande OTP
const { otpId } = await pb.collection('_users').requestOTP('[email protected]');
// L'utilisateur reçoit l'email, entre le code
const authData = await pb.collection('_users').authWithOTP(otpId, '123456');
console.log('Connecté via OTP:', pb.authStore.isValid);
// Déconnexion
pb.authStore.clear();
Dart similaire, avec gestion d'erreurs pour codes expirés (défaut : 10 min).
Sécurité : L'OTP seul est vulnérable aux attaques d'énumération ou de devinettes (codes courts). Utilisez-le en complément (ex. : avec MFA). Pour les startups, intégrez-le pour les resets mot de passe ou logins sans friction.
5. Refresh tokens : Maintenez les sessions actives
Les tokens JWT expirent pour la sécurité (défaut : 60 min). Pour éviter les reconnexions fréquentes, PocketBase supporte les refresh tokens via l'endpoint /api/collections/_users/auth-refresh.
Mécanisme
- Le token principal inclut une claim
refreshavec un token secondaire (valide plus longtemps, ex. : 7 jours). - Appelez
authRefresh()avec headerAuthorization: Bearer REFRESH_TOKEN. - Sur succès : Nouveau token principal + refresh mis à jour, plus le record utilisateur frais.
- Échec : Token invalide (ex. : expiré ou révoqué).
Important : authRefresh ne révoque pas l'ancien token ; il en génère un nouveau. Pour révoquer, changez le mot de passe ou effacez côté client.
Exemple JavaScript
const pb = new PocketBase('http://127.0.0.1:8090');
// Après connexion initiale, le refresh est dans authData.meta.refresh
try {
const refreshed = await pb.collection('_users').authRefresh();
console.log('Token rafraîchi:', pb.authStore.token);
console.log('Expire à:', refreshed.record.updated); // Timestamp frais
} catch (error) {
console.error('Refresh échoué:', error);
pb.authStore.clear(); // Force logout
}
Dart :
try {
final refreshed = await pb.collection('_users').authRefresh();
print('Rafraîchi: ${pb.authStore.token}');
} on ClientException catch (e) {
pb.authStore.clear();
}
Pour les apps mobiles/startups, implémentez un timer pour rafraîchir proactivement (ex. : toutes les 30 min). Configurez l'expiration globale dans les settings PocketBase pour aligner sur vos besoins (ex. : 24h pour tokens, 30 jours pour refresh).
Pas d'endpoint dédié pour vérifier un token : Utilisez authRefresh – succès = valide.
6. Multi-Factor Authentication (MFA) : Ajoutez une couche de sécurité
Disponible depuis v0.23, le MFA requiert deux méthodes d'auth distinctes (ex. : mot de passe + OTP). Pas d'ordre fixe : le serveur détecte et demande la seconde.
Flux MFA
- Première auth (ex. : password) : Réussit partiellement, serveur renvoie 401 avec
{ "mfaId": "uuid" }. - Seconde auth (ex. : OTP) : Incluez
mfaIden query ou body. Sur succès, token complet.
Les sessions MFA sont stockées temporairement dans la collection système _mfas.
Exemple : Password + OTP en JavaScript
const pb = new PocketBase('http://127.0.0.1:8090');
try {
// Première tentative : password
await pb.collection('_users').authWithPassword('[email protected]', 'motdepasse123');
} catch (error) {
const mfaId = error?.mfaId;
if (!mfaId) throw error; // Pas de MFA requis
// Demandez OTP à l'utilisateur
const { otpId } = await pb.collection('_users').requestOTP('[email protected]');
// UI : Modal pour entrer code
await pb.collection('_users').authWithOTP(otpId, '123456', { mfaId });
console.log('MFA réussi:', pb.authStore.isValid);
}
Dart :
try {
await pb.collection('_users').authWithPassword('[email protected]', 'motdepasse123');
} on ClientException catch (e) {
final mfaId = e.mfaId;
if (mfaId == null) rethrow;
final { otpId } = await pb.collection('_users').requestOTP('[email protected]');
await pb.collection('_users').authWithOTP(otpId, '123456', query: {'mfaId': mfaId});
}
Pour PME gérant des données sensibles (ex. : finance), activez MFA par défaut via hooks. Combinez avec OAuth2 + OTP pour une sécurité maximale sans friction excessive.
7. Gestion des tokens côté client : Persistance et sécurité
Côté client, l'SDK PocketBase gère les tokens via authStore (localStorage par défaut en JS, secure storage en Dart).
Stockage et persistance
- JavaScript/Web : Tokens en localStorage. Persistants après refresh de page.
- Dart/Flutter : Utilisez
getAuthStoreMode()pour choisir sharedPreferences ou secure (iOS Keychain/Android Keystore). - Refresh automatique : Implémentez un interceptor HTTP pour appeler
authRefreshsur 401.
Exemple d'interceptor basique en JS (avec fetch) :
pb.collection('_users').authRefresh().catch(() => pb.authStore.clear());
Meilleures pratiques
- HTTPS only : Tokens en clair sinon = vulnérable aux MITM.
- Expiration handling : Vérifiez
expclaim du JWT (parsez avec une lib comme jose). - Révoquation : Sur logout distant, changez password ou utilisez impersonation pour tokens courts.
- Pour mobile : Évitez localStorage ; utilisez secure stores. Testez sur Android 15+ pour OAuth.
Pour startups, intégrez avec des libs comme React Query pour caching des requêtes auth.
8. Exemples SDK : Du code prêt à l'emploi
Voici des snippets complets pour une app basique.
Inscription + Login + MFA
JS complet :
// Inscription
await pb.collection('_users').create({ email: '[email protected]', password: '123', passwordConfirm: '123' });
// Login avec MFA fallback
async function login(email, password) {
try {
await pb.collection('_users').authWithPassword(email, password);
} catch (e) {
if (e.mfaId) {
const { otpId } = await pb.collection('_users').requestOTP(email);
const code = await getUserOTPInput(); // UI prompt
await pb.collection('_users').authWithOTP(otpId, code, { mfaId: e.mfaId });
} else throw e;
}
}
// OAuth2
pb.collection('_users').authWithOAuth2({ provider: 'github' });
// Refresh
setInterval(() => pb.collection('_users').authRefresh().catch(() => location.reload()), 30*60*1000);
Dart équivalent pour Flutter : Utilisez flutter_secure_storage pour persistance.
Impersonation (pour admins/superusers)
Seulement pour superusers : Créez un client impersoné pour API server-to-server.
// Auth superuser
await pb.collection('_superusers').authWithPassword('[email protected]', 'superpass');
// Impersonate (token expire en 1h)
const impClient = await pb.collection('_users').impersonate('user-id', 3600);
const data = await impClient.collection('posts').getFullList();
Utile pour dashboards admin en PME.
Meilleures pratiques et pièges courants
- Sécurité : Activez MFA pour tout ; limitez les OTP à des apps non critiques. Utilisez rules comme
@request.auth.id ? true : false. - Performance : Tokens HS256 = rapides ; pas de DB lookup.
- Pièges : Pas de logout global – gérez client-side. Testez redirects OAuth en prod (HTTPS).
- Scalabilité : Pour PME grandissantes, migrez vers Postgres si SQLite limite.
- Outils : Hooks JS/Go pour custom logic (ex. : log audits).
En conclusion, l'auth de PocketBase est puissant et simple : implémentez email/OAuth/OTP/MFA en heures, pas jours. Pour votre startup, commencez par _users basique, ajoutez MFA. Questions ? Consultez la doc officielle ou le forum.