Validation des entrées
Patterns de validation avec les schémas Zod, validation des paramètres des Edge Functions et vérifications d'upload de fichiers.
Vue d'ensemble
La validation des entrées est essentielle pour la sécurité et l'intégrité des données. ScaleRocket utilise Zod pour la validation basée sur des schémas côté client et serveur, avec des vérifications supplémentaires pour les Edge Functions et les uploads de fichiers.
Validation par schéma Zod
Zod est la bibliothèque de validation recommandée. Définissez des schémas et validez les données avant le traitement :
Schéma de base
import { z } from "zod";
const userSchema = z.object({
email: z.string().email("Invalid email address"),
password: z.string().min(8, "Password must be at least 8 characters"),
name: z.string().min(1, "Name is required").max(100),
});
type UserInput = z.infer<typeof userSchema>;Valider les entrées
const result = userSchema.safeParse(formData);
if (!result.success) {
// result.error.flatten() gives a structured error object
const errors = result.error.flatten().fieldErrors;
// { email: ["Invalid email address"], password: ["..."] }
return;
}
// result.data is fully typed and safe to use
const { email, password, name } = result.data;Patterns de schéma courants
// Optional field with default
const settingsSchema = z.object({
notifications: z.boolean().default(true),
language: z.enum(["en", "fr", "de"]).default("en"),
});
// String transformations
const slugSchema = z.string().trim().toLowerCase().regex(/^[a-z0-9-]+$/);
// Number constraints
const paginationSchema = z.object({
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
});
// Union types
const idSchema = z.union([z.string().uuid(), z.string().cuid()]);Validation des formulaires côté client
Validez avant la soumission pour éviter les appels API inutiles :
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const result = userSchema.safeParse({ email, password, name });
if (!result.success) {
const errors = result.error.flatten().fieldErrors;
setErrors(errors);
return;
}
// Submit validated data
submitForm(result.data);
};Validation des paramètres des Edge Functions
Validez toujours les corps de requête entrants dans les Edge Functions :
import { z } from "zod";
const requestSchema = z.object({
userId: z.string().uuid(),
action: z.enum(["activate", "deactivate"]),
reason: z.string().max(500).optional(),
});
Deno.serve(async (req) => {
let body;
try {
body = await req.json();
} catch {
return new Response(JSON.stringify({ error: "Invalid JSON" }), { status: 400 });
}
const result = requestSchema.safeParse(body);
if (!result.success) {
return new Response(
JSON.stringify({ error: "Validation failed", details: result.error.flatten().fieldErrors }),
{ status: 400 }
);
}
// Use result.data safely
const { userId, action } = result.data;
});Validation des uploads de fichiers
Pour les uploads média admin et les pièces jointes utilisateur, validez avant le traitement :
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp", "application/pdf"];
function validateFile(file: File): string | null {
if (file.size > MAX_FILE_SIZE) {
return `File too large. Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`;
}
if (!ALLOWED_TYPES.includes(file.type)) {
return `Invalid file type. Allowed: ${ALLOWED_TYPES.join(", ")}`;
}
return null; // valid
}Avec Zod
const fileSchema = z.object({
name: z.string(),
size: z.number().max(5 * 1024 * 1024, "File exceeds 5MB limit"),
type: z.enum(["image/jpeg", "image/png", "image/webp", "application/pdf"], {
errorMap: () => ({ message: "Unsupported file type" }),
}),
});Checklist de validation
- Valider toutes les entrées de formulaire avant la soumission (côté client)
- Valider tous les corps de requête des Edge Functions (côté serveur)
- Utiliser
safeParseau lieu deparsepour éviter de lancer des exceptions - Définir des longueurs maximales sur les champs string pour empêcher les abus de payload
- Valider la taille et le type MIME des fichiers avant l'upload
- Ne jamais faire confiance à la validation côté client seule ; toujours re-valider côté serveur
Conseils
- Partagez les schémas Zod entre le client et le serveur en les plaçant dans un package partagé.
- Utilisez
z.coercepour les paramètres de requête et les données de formulaire qui arrivent sous forme de chaînes de caractères. - Combinez Zod avec React Hook Form en utilisant
@hookform/resolvers/zodpour une validation de formulaire intégrée. - Assainissez le contenu HTML (ex. articles de blog) avec une bibliothèque comme
dompurifyaprès la validation Zod.
Fini ? Marquez cette page comme terminée.