Empêcher les mauvaises entrées
Dans cette dernière étape, nous allons explorer des techniques avancées pour empêcher les mauvaises entrées et améliorer l'intégrité des données dans MongoDB grâce à des stratégies de validation complètes.
Préparer l'environnement
Continuons dans notre shell MongoDB :
mongosh
Changeons de base de données existante :
use dataValidationLab
Création d'un schéma de validation robuste
Nous allons créer un schéma de validation complet pour une collection'registrations' :
db.createCollection("registrations", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["username", "email", "password", "registrationDate"],
properties: {
username: {
bsonType: "string",
minLength: 3,
maxLength: 20,
pattern: "^[a-zA-Z0-9_]+$",
description:
"Le nom d'utilisateur doit être alphanumérique, de 3 à 20 caractères"
},
email: {
bsonType: "string",
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
description: "Doit être une adresse e-mail valide"
},
password: {
bsonType: "string",
minLength: 8,
description: "Le mot de passe doit avoir au moins 8 caractères",
pattern:
"^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$"
},
registrationDate: {
bsonType: "date",
description: "La date d'inscription doit être une date valide"
}
}
}
},
validationAction: "error",
validationLevel: "strict"
});
Mise en œuvre d'un middleware d'empêchement d'entrées
Créez une fonction pour valider les entrées avant insertion :
function safeRegister(userData) {
// Nettoyer et valider les entrées
const sanitizedData = {
username: userData.username.trim().toLowerCase(),
email: userData.email.trim().toLowerCase(),
password: userData.password,
registrationDate: new Date()
};
// Validations personnalisées supplémentaires
if (sanitizedData.username.length < 3) {
throw new Error("Le nom d'utilisateur est trop court");
}
if (db.registrations.findOne({ username: sanitizedData.username })) {
throw new Error("Le nom d'utilisateur existe déjà");
}
if (db.registrations.findOne({ email: sanitizedData.email })) {
throw new Error("L'e-mail est déjà enregistré");
}
try {
// Tenter d'insérer avec la validation de MongoDB
db.registrations.insertOne(sanitizedData);
print("Inscription réussie :", sanitizedData.username);
} catch (error) {
print("Inscription échouée :", error.message);
// Journaliser les tentatives d'inscription échouées
db.registrationAttempts.insertOne({
attemptData: userData,
errorMessage: error.message,
timestamp: new Date()
});
}
}
// Tester l'empêchement d'entrées
function testRegistrations() {
const testCases = [
// Inscription valide
{
username: "john_doe",
email: "[email protected]",
password: "Strong!Pass123"
},
// Cas invalides
{ username: "ab", email: "invalid-email", password: "short" },
{ username: "john_doe!", email: "[email protected]", password: "WeakPass" },
{
username: "special_chars!",
email: "invalid@email",
password: "NoSpecialChar123"
}
];
testCases.forEach((testCase) => {
print("\nTest d'inscription :");
printjson(testCase);
safeRegister(testCase);
});
}
// Exécuter les tests d'inscription
testRegistrations();
Vérifier les tentatives d'inscription
Vérifions les tentatives d'inscription journalisées :
print("Tentatives d'inscription échouées :");
db.registrationAttempts.find();
Meilleures pratiques pour l'empêchement d'entrées
- Utiliser une validation de schéma complète
- Mettre en œuvre une nettoyage d'entrées côté serveur
- Utiliser des motifs regex pour une validation stricte
- Journaliser et suivre les tentatives d'entrée invalides
- Mettre en œuvre une logique de validation personnalisée supplémentaire