Prevenir entradas incorrectas
En este último paso, exploraremos técnicas avanzadas para prevenir entradas incorrectas y mejorar la integridad de los datos en MongoDB a través de estrategias de validación exhaustivas.
Preparar el entorno
Continuemos en la shell de MongoDB:
mongosh
Cambiemos a nuestra base de datos existente:
use dataValidationLab
Crear un esquema de validación robusto
Crearemos un esquema de validación exhaustivo para una colección'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:
"El nombre de usuario debe ser alfanumérico, de 3 a 20 caracteres"
},
email: {
bsonType: "string",
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
description: "Debe ser una dirección de correo electrónico válida"
},
password: {
bsonType: "string",
minLength: 8,
description: "La contraseña debe tener al menos 8 caracteres",
pattern:
"^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$"
},
registrationDate: {
bsonType: "date",
description: "La fecha de registro debe ser una fecha válida"
}
}
}
},
validationAction: "error",
validationLevel: "strict"
});
Implementar middleware de prevención de entrada
Crea una función para validar la entrada antes de la inserción:
function safeRegister(userData) {
// Limpiar y validar la entrada
const sanitizedData = {
username: userData.username.trim().toLowerCase(),
email: userData.email.trim().toLowerCase(),
password: userData.password,
registrationDate: new Date()
};
// Validaciones personalizadas adicionales
if (sanitizedData.username.length < 3) {
throw new Error("El nombre de usuario es demasiado corto");
}
if (db.registrations.findOne({ username: sanitizedData.username })) {
throw new Error("El nombre de usuario ya existe");
}
if (db.registrations.findOne({ email: sanitizedData.email })) {
throw new Error("El correo electrónico ya está registrado");
}
try {
// Intentar insertar con validación de MongoDB
db.registrations.insertOne(sanitizedData);
print("Registro exitoso:", sanitizedData.username);
} catch (error) {
print("Registro fallido:", error.message);
// Registrar intentos de registro fallidos
db.registrationAttempts.insertOne({
attemptData: userData,
errorMessage: error.message,
timestamp: new Date()
});
}
}
// Probar la prevención de entrada
function testRegistrations() {
const testCases = [
// Registro válido
{
username: "john_doe",
email: "[email protected]",
password: "Strong!Pass123"
},
// Casos no válidos
{ 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("\nProbando registro:");
printjson(testCase);
safeRegister(testCase);
});
}
// Ejecutar las pruebas de registro
testRegistrations();
Revisar los intentos de registro
Verifica los intentos de registro registrados:
print("Intentos de registro fallidos:");
db.registrationAttempts.find();
Mejores prácticas para la prevención de entrada
- Utilizar validación de esquema exhaustiva
- Implementar la limpieza de entrada en el servidor
- Utilizar patrones de expresiones regulares para validación estricta
- Registrar y rastrear intentos de entrada no válidos
- Implementar lógica de validación personalizada adicional