Routes dynamiques et authentification par cookies avec net/http : Implémentation de DeadDrop
Poursuivant notre série sur net/http pur, nous implémentons le routage dynamique pour le service DeadDrop. Les utilisateurs pourront consulter des secrets via des liens comme /secret/{id}. Le routeur standard ne prend pas en charge les paramètres de chemin avant Go 1.22, nous écrivons donc notre propre analyseur.
Le gestionnaire est enregistré à /secret/ avec une barre oblique finale — cela capture tous les chemins enfants. Nous extrayons l'ID manuellement depuis r.URL.Path.
func extractIDFromPath(path string) (string, bool) {
const prefix = "/secret/"
if !strings.HasPrefix(path, prefix) {
return "", false
}
id := strings.TrimPrefix(path, prefix)
if id == "" || strings.Contains(id, "/") {
return "", false
}
return id, true
}
La fonction vérifie le préfixe, le supprime, et exclut les ID invalides (vides ou contenant /). Cela offre une protection basique contre les requêtes malformées.
SecretHandler avec injection de dépendances
Nous créons une structure de gestionnaire pour l'injection de dépendances :
type SecretHandler struct {
// placeholder pour l'injection de dépendances
}
func NewSecretHandler() *SecretHandler {
return &SecretHandler{}
}
func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
id, ok := url.ExtractIDFromPath(r.URL.Path)
if !ok {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusOK)
w.Write([]byte("Secret demandé avec l'ID : " + id))
}
Enregistrez-le dans router.go : mux.Handle("/secret/", secretHandler). Testez les cas limites :
/secret/12345/→ 404/secret/→ 404/secret/axQ/233→ 404/secret/ad31H234→ OK avec ID
Cas d'utilisation pour récupérer un secret
Définissez la requête et la réponse :
type GetSecretRequest struct {
ID string
Password string
}
type GetSecretResponse struct {
ID string
Message string
FileName string
FileExt string
HasFile bool
ExpiresAt time.Time
}
Logique du cas d'utilisation :
- Récupérez le secret depuis le stockage
- Vérifiez l'expiration (
time.After()), supprimez ceux expirés - Vérifiez le mot de passe via
CheckPasswordHash - Retournez les données ou une erreur
Authentification par cookies
Pour protéger les téléchargements de fichiers, nous implémentons l'authentification via des cookies. Après une vérification réussie du mot de passe, définissez un cookie de session avec un jeton d'accès chiffré.
- Avantages : sans état, évolutif, pas de stockage de session
- Paramètres du cookie : HttpOnly, Secure, SameSite=Strict
Lors d'une requête /download/{id} :
- Extrayez l'ID du chemin
- Lisez le cookie
auth_token - Décodez et vérifiez le jeton (ID + hachage du mot de passe + nonce)
- Si valide — servez le fichier
Structure du jeton d'accès
Le jeton est formé comme base64(ID + ":" + hash + ":" + nonce), où :
hash = HMAC-SHA256(ID + mot de passe, cléSecrète)nonce— un numéro à usage unique pour protéger contre les attaques par rejeu
Exemple de validation :
func validateDownloadToken(id, token string) bool {
// décodez le jeton
// extrayez le hachage et le nonce
// recalculez le HMAC
// comparez
return true // ou false
}
Flux complet du secret
- Création : POST
/create→ générez l'ID, hachez le mot de passe, sauvegardez - Consultation : GET
/secret/{id}→ formulaire de saisie du mot de passe - Authentification : POST mot de passe → cookie + redirection
- Téléchargement : GET
/download/{id}→ vérifiez le cookie → fichier - Nettoyage : TTL expiré → suppression
Prototype d'interface : page avec champ de mot de passe, bouton "Ouvrir". Après succès — contenu + lien de fichier.
Tests de routage
| Chemin de test | Attente | Résultat |
|-----------|-------------|--------|
| /secret/123/ | 404 | 404 |
| /secret/ | 404 | 404 |
| /secret/id/avec/barre | 404 | 404 |
| /secret/valid123 | OK : "ID : valid123" | OK |
Les cas limites couvrent la sécurité de l'analyseur.
Points clés
- Routes dynamiques : analyse manuelle de
r.URL.Pathsans routeurs tiers - Sécurité : validation de l'ID, vérifications des barres obliques, TTL pour les secrets
- Authentification : cookie avec jeton HMAC au lieu de sessions
- Architecture : cas d'utilisation + injection de dépendances, logique propre en dehors des gestionnaires
- Évolutivité : sans état, prêt pour le clustering
— Editorial Team
Aucun commentaire pour le moment.